AutomationFlowsAI & RAG › Mission Planner (llm Plans, N8n Executes)

Mission Planner (llm Plans, N8n Executes)

09 - Mission Planner (LLM Plans, n8n Executes). Uses formTrigger, chainLlm, lmChatAnthropic, @fhnw-rover/n8n-nodes-ros2. Event-driven trigger; 8 nodes.

Event trigger★★★★☆ complexityAI-powered8 nodesForm TriggerChain LlmAnthropic Chat@Fhnw Rover/N8N Nodes Ros2Form
AI & RAG Trigger: Event Nodes: 8 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Chainllm → Form Trigger recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "demo-09-planner",
  "name": "09 - Mission Planner (LLM Plans, n8n Executes)",
  "nodes": [
    {
      "parameters": {
        "path": "plan-mission",
        "formTitle": "Give the Rover a Mission",
        "formDescription": "Describe what you want in plain language, for example: visit the lake and the tree, flashing blue, then park on the dock. The model turns it into a plan and n8n executes the plan step by step.",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Mission",
              "fieldType": "textarea",
              "requiredField": true
            }
          ]
        },
        "responseMode": "lastNode",
        "options": {}
      },
      "id": "plan-form",
      "name": "Mission Form",
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.2,
      "position": [
        -560,
        0
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Turn this mission into a plan for a rover.\n\nMission: {{ $json.Mission }}\n\nThe rover can drive to these named places only: lake, tree, house, mountain, dock, center.\nIts LED can be: red, green, blue, yellow, magenta, cyan, white, off.\n\nAnswer with JSON ONLY, no prose and no code fences, in exactly this shape:\n{\"summary\": \"one sentence\", \"steps\": [{\"place\": \"lake\", \"led\": \"blue\", \"why\": \"short reason\"}]}\n\nUse at most 6 steps. Every place must be one of the allowed names.",
        "messages": {
          "messageValues": [
            {
              "message": "You are a mission planner for a small rover. You only ever answer with valid JSON matching the requested shape."
            }
          ]
        },
        "batching": {}
      },
      "id": "plan-llm",
      "name": "Plan the Mission",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.7,
      "position": [
        -340,
        0
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-6",
          "cachedResultName": "Claude Sonnet 4.6"
        },
        "options": {}
      },
      "id": "plan-model",
      "name": "Claude Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.5,
      "position": [
        -340,
        200
      ],
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// The plan arrives as text. Parse it and hand one item per step to the\n// loop below, so the rover is driven by deterministic n8n execution rather\n// than by the model calling tools itself.\nconst PLACES = ['lake', 'tree', 'house', 'mountain', 'dock', 'center'];\nconst LEDS = ['red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'off'];\n\nconst raw = $input.first().json.text ?? $input.first().json.output ?? '';\nconst match = String(raw).match(/\\{[\\s\\S]*\\}/);\nif (!match) {\n  throw new Error('The model did not return JSON: ' + String(raw).slice(0, 200));\n}\n\nconst plan = JSON.parse(match[0]);\nconst steps = (plan.steps || [])\n  .filter((s) => PLACES.includes(s.place))\n  .slice(0, 6)\n  .map((s, i) => ({\n    json: {\n      index: i + 1,\n      place: s.place,\n      led: LEDS.includes(s.led) ? s.led : 'blue',\n      why: s.why || '',\n      summary: plan.summary || '',\n      total: 0,\n    },\n  }));\n\nif (!steps.length) {\n  throw new Error('The plan contained no usable steps.');\n}\nsteps.forEach((s) => (s.json.total = steps.length));\nreturn steps;"
      },
      "id": "plan-parse",
      "name": "Parse the Plan",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -120,
        0
      ]
    },
    {
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "id": "plan-loop",
      "name": "One Step at a Time",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        100,
        0
      ]
    },
    {
      "parameters": {
        "serviceName": {
          "__rl": true,
          "mode": "id",
          "value": "/rover/set_led"
        },
        "serviceType": {
          "__rl": true,
          "mode": "id",
          "value": "rover_interfaces/srv/SetLed"
        },
        "requestInputMode": "raw",
        "requestJson": "={{ JSON.stringify({ color: $json.led, blink: false }) }}"
      },
      "id": "plan-led",
      "name": "Set the Step LED",
      "type": "@fhnw-rover/n8n-nodes-ros2.rosServiceCall",
      "typeVersion": 1,
      "position": [
        340,
        120
      ],
      "credentials": {
        "rosBridgeApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "sendGoalAndWait",
        "serverName": {
          "__rl": true,
          "mode": "id",
          "value": "/rover/patrol"
        },
        "actionType": {
          "__rl": true,
          "mode": "id",
          "value": "rover_interfaces/action/Patrol"
        },
        "goalInputMode": "raw",
        "goalJson": "={{ JSON.stringify({ waypoint_names: [$('One Step at a Time').item.json.place], loops: 1, dock_when_done: false }) }}",
        "includeFeedback": false,
        "timeoutMs": 180000
      },
      "id": "plan-drive",
      "name": "Drive to the Step",
      "type": "@fhnw-rover/n8n-nodes-ros2.rosAction",
      "typeVersion": 1,
      "position": [
        560,
        120
      ],
      "credentials": {
        "rosBridgeApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "completion",
        "respondWith": "text",
        "completionTitle": "Mission finished",
        "completionMessage": "={{ $('Parse the Plan').first().json.summary }}\n\nSteps executed: {{ $('Parse the Plan').all().map(i => i.json.index + '. ' + i.json.place + ' (' + i.json.led + ') \u2014 ' + i.json.why).join('\\n') }}",
        "options": {}
      },
      "id": "plan-done",
      "name": "Report Back",
      "type": "n8n-nodes-base.form",
      "typeVersion": 1,
      "position": [
        340,
        -120
      ]
    }
  ],
  "connections": {
    "Mission Form": {
      "main": [
        [
          {
            "node": "Plan the Mission",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Plan the Mission",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Plan the Mission": {
      "main": [
        [
          {
            "node": "Parse the Plan",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse the Plan": {
      "main": [
        [
          {
            "node": "One Step at a Time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "One Step at a Time": {
      "main": [
        [
          {
            "node": "Report Back",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set the Step LED",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set the Step LED": {
      "main": [
        [
          {
            "node": "Drive to the Step",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Drive to the Step": {
      "main": [
        [
          {
            "node": "One Step at a Time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

09 - Mission Planner (LLM Plans, n8n Executes). Uses formTrigger, chainLlm, lmChatAnthropic, @fhnw-rover/n8n-nodes-ros2. Event-driven trigger; 8 nodes.

Source: https://github.com/sacovo/n8n-nodes-ros2/blob/5c0a3f2fde70374468e4f27f89256af0a4cee400/demo/workflows/09-mission-planner.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Episode 11: AI shorts factory app. Uses httpRequest, googleSheets, lmChatOpenAi, lmChatOllama. Event-driven trigger; 96 nodes.

HTTP Request, Google Sheets, OpenAI Chat +15
AI & RAG

My workflow 53. Uses formTrigger, httpRequest, lmChatOpenAi, form. Event-driven trigger; 74 nodes.

Form Trigger, HTTP Request, OpenAI Chat +15
AI & RAG

Content - Newsletter Agent. Uses formTrigger, chainLlm, outputParserStructured, httpRequest. Event-driven trigger; 91 nodes.

Form Trigger, Chain Llm, Output Parser Structured +8
AI & RAG

Content - Newsletter Agent. Uses formTrigger, chainLlm, outputParserStructured, httpRequest. Event-driven trigger; 87 nodes.

Form Trigger, Chain Llm, Output Parser Structured +7
AI & RAG

Host Your Own AI Deep Research Agent with n8n, Apify and OpenAI. Uses outputParserStructured, lmChatOpenAi, formTrigger, chainLlm. Event-driven trigger; 87 nodes.

Output Parser Structured, OpenAI Chat, Form Trigger +7