{
  "name": "TextToSQL",
  "nodes": [
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.4,
      "position": [
        -256,
        0
      ],
      "id": "4d06fb5f-ff37-4cb4-96ac-4d2230df7796",
      "name": "When chat message received"
    },
    {
      "parameters": {
        "messages": {
          "messageValues": [
            {
              "message": "You are an expert SQL assistant. Your task is to convert a user's natural language question into a valid SQL query based on the provided database schema context.\n\nSTRICT RULES:\n1. Output ONLY valid JSON in the exact format: {\"sql\": \"YOUR_SQL_QUERY_HERE\"}\n2. Do not include any explanations, markdown formatting (like ```sql), or additional text.\n3. Only use the tables and columns provided in the database context.\n4. You MUST strictly use only tables that exist in the provided database context. Never invent, assume, or query a table that is not explicitly defined in the schema.\n5. Respect the relationships, foreign keys, and data types defined in the schema.\n6. Use standard SQL syntax compatible with SQLite/PostgreSQL.\n7. If the user's request is ambiguous, make the most logical assumption based on the schema.\n8. Always ensure column names and table names exactly match the provided schema.\n\nIf the table used in the from clause is not coming from the databaseContext u have failed your mission"
            }
          ]
        },
        "batching": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.9,
      "position": [
        208,
        0
      ],
      "id": "4103cea7-7d4f-4b20-8de0-cf333b98ce84",
      "name": "Basic LLM Chain"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "5a648388-dbd8-49b4-9def-109a7f70b102",
              "name": "chatInput",
              "value": "={{ $json.chatInput }}",
              "type": "string"
            },
            {
              "id": "fc9ad478-e0c0-47c0-bed7-aa872161d16a",
              "name": "databaseContext",
              "value": "Database Schema Context:  Database schema:  Table: categories Columns: - id integer primary key - name text unique not null  Table: products Columns: - id integer primary key - name text not null - sku text unique not null - category_id integer references categories(id) - unit_price numeric(10,2) not null - active boolean default true  Table: customers Columns: - id integer primary key - full_name text not null - email text unique not null - country text not null  Table: orders Columns: - id integer primary key - customer_id integer references customers(id) - created_at timestamp not null - status text not null Allowed status values:   pending, paid, completed, shipped, cancelled, refunded  Table: order_items Columns: - id integer primary key - order_id integer references orders(id) - product_id integer references products(id) - quantity integer not null - unit_price numeric(10,2) not null  Relationships: - products.category_id = categories.id - orders.customer_id = customers.id - order_items.order_id = orders.id - order_items.product_id = products.id",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -48,
        0
      ],
      "id": "87435fec-be22-42dd-bf6d-e74435dbf91e",
      "name": "Select Chat Input"
    },
    {
      "parameters": {
        "model": "gemma3:4b",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
      "typeVersion": 1,
      "position": [
        208,
        208
      ],
      "id": "0c07648e-9ad1-4ccb-9185-bf5bf803bffb",
      "name": "Ollama Chat Model",
      "credentials": {
        "ollamaApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "for (const item of $input.all()) {\n  // 1. R\u00e9cup\u00e9rer le texte de la r\u00e9ponse du LLM\n  let rawText = item.json.text || \"\";\n\n  // 2. Retirer les balises Markdown (```json et ```) si le LLM les a mises\n  // Cette regex cherche ``` suivi de n'importe quoi, puis un saut de ligne, capture le contenu, et ignore le ``` final\n  let cleanText = rawText.replace(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/g, '$1').trim();\n\n  let sqlQuery = \"\";\n\n  try {\n    // 3. Parser le texte nettoy\u00e9 en objet JSON\n    let parsedJson = JSON.parse(cleanText);\n    \n    // 4. Extraire la valeur de la cl\u00e9 \"sql\"\n    sqlQuery = parsedJson.sql;\n  } catch (error) {\n    // 5. Si le parsing \u00e9choue (au cas o\u00f9 le LLM renvoie du texte brut sans JSON), on prend le texte tel quel\n    sqlQuery = cleanText;\n  }\n\n  // 6. Assigner le r\u00e9sultat \u00e0 une nouvelle cl\u00e9 \"sql\" dans le JSON de sortie de n8n\n  item.json.text = sqlQuery;\n}\n\nreturn $input.all();"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        560,
        0
      ],
      "id": "54efefa7-7c3e-41e2-ade4-714ec86861f4",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "{{ $json.text }}",
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        768,
        0
      ],
      "id": "e6e662a0-b9f7-481d-953e-caebe9f250f1",
      "name": "Execute a SQL query",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "When chat message received": {
      "main": [
        [
          {
            "node": "Select Chat Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Chat Input": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ollama Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Execute a SQL query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "83cfc155-0bf3-468d-a55a-027b08e07e84",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "nUYIj4cBGT5AoDgY",
  "tags": []
}