{
  "name": "mw_ai_host_n8n_rag_demo",
  "nodes": [
    {
      "parameters": {
        "content": "## Agent Tools for RAG",
        "height": 528.85546469693,
        "width": 583.4552380860637,
        "color": 4
      },
      "id": "11c93389-5509-4447-baeb-611c2843704e",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        6384,
        224
      ],
      "typeVersion": 1
    },
    {
      "parameters": {},
      "id": "e73ea582-fab6-4fe3-93d3-bd5e560eb966",
      "name": "Postgres Chat Memory1",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "position": [
        5792,
        592
      ],
      "notesInFlow": false,
      "typeVersion": 1,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "content": "## RAG AI Agent with Chat Interface",
        "height": 464.8027193303974,
        "width": 1035.6381264595484
      },
      "id": "7a2aca2e-6161-4231-b572-4437ff70a566",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5344,
        288
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "31365fbf-d520-43a7-8742-2d56434e3347",
      "name": "Respond to Webhook1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        6208,
        368
      ],
      "typeVersion": 1.1
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9a9a245e-f1a1-4282-bb02-a81ffe629f0f",
              "name": "chatInput",
              "type": "string",
              "value": "={{ $json?.chatInput || $json.body.chatInput }}"
            },
            {
              "id": "b80831d8-c653-4203-8706-adedfdb98f77",
              "name": "sessionId",
              "type": "string",
              "value": "={{ $json?.sessionId || $json.body.sessionId}}"
            }
          ]
        },
        "options": {}
      },
      "id": "68c32fe4-d088-480a-8346-313966df71a9",
      "name": "Edit Fields1",
      "type": "n8n-nodes-base.set",
      "position": [
        5648,
        368
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "bf4dd093-bb02-472c-9454-7ab9af97bd1d",
        "authentication": "jwtAuth",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "607f8611-4198-41b0-9804-1b10e8aeed82",
      "name": "Webhook1",
      "type": "n8n-nodes-base.webhook",
      "position": [
        5392,
        560
      ],
      "webhookId": "bf4dd093-bb02-472c-9454-7ab9af97bd1d",
      "typeVersion": 2,
      "credentials": {
        "jwtAuth": {
          "id": "N3cBbU578Y2LxzZD",
          "name": "JWT Auth account"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.chatInput }}",
        "options": {
          "systemMessage": "You are a personal assistant who helps answer questions from a corpus of documents. The documents are either text based (Txt, docs, extracted PDFs, etc.) or tabular data (CSVs or Excel documents).\n\nYou are given tools to perform RAG in the 'documents' table, look up the documents available in your knowledge base in the 'document_metadata' table, extract all the text from a given document, and query the tabular files with SQL in the 'document_rows' table.\n\nAlways start by performing RAG unless the users asks you to check a document or the question requires a SQL query for tabular data (fetching a sum, finding a max, something a RAG lookup would be unreliable for). If RAG doesn't help, then look at the documents that are available to you, find a few that you think would contain the answer, and then analyze those.\n\nAlways tell the user if you didn't find the answer. Don't make something up just to please them."
        }
      },
      "id": "24894e00-fb76-4b90-a8d2-11f404c47672",
      "name": "RAG AI Agent1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        5872,
        368
      ],
      "typeVersion": 1.6
    },
    {
      "parameters": {
        "content": "## Run Each Node Once to Set Up Database Tables",
        "height": 300,
        "width": 632,
        "color": 3
      },
      "id": "e7e8a3fe-8219-4868-bb41-e5b2c72c67d0",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4688,
        448
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "CREATE TABLE document_metadata (\n    id TEXT PRIMARY KEY,\n    title TEXT,\n    created_at TIMESTAMP DEFAULT NOW(),\n    schema TEXT\n);",
        "options": {}
      },
      "id": "dcf6c1b4-26be-4e89-b942-ce79238f1077",
      "name": "Create Document Metadata Table1",
      "type": "n8n-nodes-base.postgres",
      "position": [
        4768,
        544
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "CREATE TABLE document_rows (\n    id SERIAL PRIMARY KEY,\n    dataset_id TEXT REFERENCES document_metadata(id),\n    row_data JSONB  -- Store the actual row data\n);",
        "options": {}
      },
      "id": "4c7916a0-f3ed-4c10-9090-f94400522e8a",
      "name": "Create Document Rows Table (for Tabular Data)1",
      "type": "n8n-nodes-base.postgres",
      "position": [
        5072,
        544
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Use this tool to fetch all available documents, including the table schema if the file is a CSV or Excel file.",
        "operation": "select",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "document_metadata",
          "cachedResultName": "document_metadata"
        },
        "returnAll": true,
        "options": {}
      },
      "id": "a2b35881-a505-4af7-af0c-69a4fcf1b6ee",
      "name": "List Documents1",
      "type": "n8n-nodes-base.postgresTool",
      "position": [
        5920,
        592
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Given a file ID, fetches the text from the document.",
        "operation": "executeQuery",
        "query": "SELECT \n    string_agg(text, ' ') as document_text\nFROM documents_pg\n  WHERE metadata->>'file_id' = $1\nGROUP BY metadata->>'file_id';",
        "options": {
          "queryReplacement": "={{ $fromAI('file_id') }}"
        }
      },
      "id": "9aee7e37-7951-424b-a095-4ffb98a85560",
      "name": "Get File Contents1",
      "type": "n8n-nodes-base.postgresTool",
      "position": [
        6064,
        592
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Run a SQL query - use this to query from the document_rows table once you know the file ID (which is the file path) you are querying. dataset_id is the file_id (file path) and you are always using the row_data for filtering, which is a jsonb field that has all the keys from the file schema given in the document_metadata table.\n\nExample query:\n\nSELECT AVG((row_data->>'revenue')::numeric)\nFROM document_rows\nWHERE dataset_id = '/data/shared/document.csv';\n\nExample query 2:\n\nSELECT \n    row_data->>'category' as category,\n    SUM((row_data->>'sales')::numeric) as total_sales\nFROM dataset_rows\nWHERE dataset_id = '/data/shared/document2.csv'\nGROUP BY row_data->>'category';",
        "operation": "executeQuery",
        "query": "{{ $fromAI('sql_query') }}",
        "options": {}
      },
      "id": "37aab605-4bdb-4581-b414-b0f786400451",
      "name": "Query Document Rows1",
      "type": "n8n-nodes-base.postgresTool",
      "position": [
        6224,
        592
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "Ministral-3-14B-Instruct-2512",
          "mode": "list",
          "cachedResultName": "Ministral-3-14B-Instruct-2512"
        },
        "options": {}
      },
      "id": "5bdf736d-57e6-4db2-b05a-470aea443617",
      "name": "Ollama (Change Base URL)1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        5648,
        592
      ],
      "typeVersion": 1.2,
      "credentials": {
        "openAiApi": {
          "id": "Xyj6iByncXj1pvGF",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "documents",
        "toolDescription": "Use RAG to look up information in the knowledgebase.",
        "tableName": "documents_pg",
        "options": {}
      },
      "id": "6cf22b57-578d-477c-9871-8d223a480c82",
      "name": "Postgres PGVector Store3",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "position": [
        6544,
        368
      ],
      "typeVersion": 1,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "model": "Qwen3-Embedding-8B",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1.2,
      "position": [
        6704,
        560
      ],
      "id": "679b7f61-5f1b-4ca0-a04b-2f44addcca36",
      "name": "Embeddings OpenAI",
      "credentials": {
        "openAiApi": {
          "id": "Xyj6iByncXj1pvGF",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "jsonMode": "expressionData",
        "jsonData": "={{ $json.data || $json.text || $json.concatenated_data }}",
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "=file_id",
                "value": "={{ $('Set File ID').first().json.file_id }}"
              },
              {
                "name": "file_title",
                "value": "={{ $('Set File ID').first().json.file_title }}"
              }
            ]
          }
        }
      },
      "id": "b3feb98d-712b-4f89-9645-3ce77022230b",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        7424,
        1456
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "content": "## Tool to watch filesystem and add embeddings for new files",
        "height": 867,
        "width": 3073,
        "color": 5
      },
      "id": "a269178d-0f86-49a4-a6bc-0b6b9b28758a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4672,
        864
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "id": "e26fad26-d804-4526-8779-7ce922f56fa6",
      "name": "Extract Document Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        6624,
        1456
      ],
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "10646eae-ae46-4327-a4dc-9987c2d76173",
              "name": "file_id",
              "type": "string",
              "value": "={{ $json.path }}"
            },
            {
              "id": "f4536df5-d0b1-4392-bf17-b8137fb31a44",
              "name": "file_type",
              "type": "string",
              "value": "={{ $json.path.split(/[\\\\/]/).pop().split('.').pop(); }}"
            },
            {
              "id": "77d782de-169d-4a46-8a8e-a3831c04d90f",
              "name": "file_title",
              "type": "string",
              "value": "={{ $json.path.split(/[\\\\/]/).pop().split('.').slice(0, -1).join('.'); }}"
            }
          ]
        },
        "options": {}
      },
      "id": "60ab0316-a1a5-4732-8390-e2310562385a",
      "name": "Set File ID",
      "type": "n8n-nodes-base.set",
      "position": [
        5104,
        1136
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "operation": "pdf",
        "options": {}
      },
      "id": "98b24425-2f36-40c2-a352-bde8b3dd8d33",
      "name": "Extract PDF Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        6624,
        896
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "id": "75fa9a6c-7da5-41fd-9fbb-4c6360401fba",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        6656,
        1088
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "fieldsToSummarize": {
          "values": [
            {
              "aggregation": "concatenate",
              "field": "data"
            }
          ]
        },
        "options": {}
      },
      "id": "6f15bb0e-613c-4ddd-9da7-5193adcd474b",
      "name": "Summarize",
      "type": "n8n-nodes-base.summarize",
      "position": [
        6864,
        1168
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "pdf"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "2ae7faa7-a936-4621-a680-60c512163034",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "xlsx"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fc193b06-363b-4699-a97d-e5a850138b0e",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "=csv"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b69f5605-0179-4b02-9a32-e34bb085f82d",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "txt"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": 3
        }
      },
      "id": "1acc250c-6ea0-4bbf-8e1b-fc170d602f4d",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        5952,
        1120
      ],
      "typeVersion": 3
    },
    {
      "parameters": {
        "operation": "xlsx",
        "options": {}
      },
      "id": "65b05c11-1bfd-450f-9f9e-2ceb0c043865",
      "name": "Extract from Excel",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        6432,
        1088
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "f422e2e0-381c-46ea-8f38-3f58c501d8b9",
              "name": "schema",
              "type": "string",
              "value": "={{ $('Extract from Excel').isExecuted ? $('Extract from Excel').first().json.keys().toJsonString() : $('Extract from CSV').first().json.keys().toJsonString() }}"
            },
            {
              "id": "bb07c71e-5b60-4795-864c-cc3845b6bc46",
              "name": "data",
              "type": "string",
              "value": "={{ $json.concatenated_data }}"
            }
          ]
        },
        "options": {}
      },
      "id": "0c441e6d-f8bd-48bb-a2e7-c184a324eca4",
      "name": "Set Schema",
      "type": "n8n-nodes-base.set",
      "position": [
        7296,
        1024
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "b3e6f554-98d8-483c-9953-fb4a2350837a",
      "name": "Extract from CSV",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        6432,
        1264
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "id": "6eb1ac43-3fee-4c0c-bd16-1e2b6fae773d",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        4960,
        976
      ],
      "typeVersion": 3
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "document_metadata",
          "cachedResultName": "document_metadata"
        },
        "columns": {
          "value": {
            "id": "={{ $('Set File ID').item.json.file_id }}",
            "title": "={{ $('Set File ID').item.json.file_title }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": true,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "type": "dateTime",
              "display": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "schema",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "schema",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "id": "788cd5b1-7ad2-4d13-8ebf-98e33d49427a",
      "name": "Insert Document Metadata",
      "type": "n8n-nodes-base.postgres",
      "position": [
        5600,
        1008
      ],
      "executeOnce": true,
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "document_rows",
          "cachedResultName": "document_rows"
        },
        "columns": {
          "value": {
            "row_data": "={{ $json.toJsonString().replaceAll(/'/g, \"''\") }}",
            "dataset_id": "={{ $('Set File ID').item.json.file_id }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "number",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "dataset_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "dataset_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_data",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "row_data",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "id": "1b9e959b-8213-4b1f-8810-45c4c4ad31db",
      "name": "Insert Table Rows",
      "type": "n8n-nodes-base.postgres",
      "position": [
        6656,
        1264
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "document_metadata",
          "cachedResultName": "document_metadata"
        },
        "columns": {
          "value": {
            "id": "={{ $('Set File ID').item.json.file_id }}",
            "schema": "={{ $json.schema }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": true,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "type": "dateTime",
              "display": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "schema",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "schema",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "id": "69ead8ca-9897-480f-ab54-78eb70c19fff",
      "name": "Update Schema for Document Metadata",
      "type": "n8n-nodes-base.postgres",
      "position": [
        7520,
        1024
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "triggerOn": "folder",
        "path": "/home/node/.n8n-files",
        "events": [
          "change",
          "add",
          "addDir"
        ],
        "options": {}
      },
      "id": "b63fe449-e3ac-467b-9445-797c012687e7",
      "name": "Local File Trigger",
      "type": "n8n-nodes-base.localFileTrigger",
      "position": [
        4736,
        976
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "fileSelector": "={{ $('Set File ID').item.json.file_id }}",
        "options": {
          "dataPropertyName": "=data"
        }
      },
      "id": "e132c61b-4acb-4fe5-93ec-e8cc54608575",
      "name": "Read/Write Files from Disk",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        5760,
        1136
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "chunkSize": 400,
        "options": {}
      },
      "id": "0af6056c-a2f1-44f2-8eaa-fa24d9e1f2e8",
      "name": "Recursive Character Text Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "position": [
        7312,
        1584
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "DO $$\nBEGIN\n    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'documents_pg') THEN\n        EXECUTE 'DELETE FROM documents_pg WHERE metadata->>''file_id'' LIKE ''%' || $1 || '%''';\n    END IF;\nEND\n$$;",
        "options": {
          "queryReplacement": "={{ $json.file_id }}"
        }
      },
      "id": "4f22bc8a-89f8-459b-b70f-daf3553a863e",
      "name": "Delete Old Doc Records",
      "type": "n8n-nodes-base.postgres",
      "position": [
        5280,
        1008
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "DELETE FROM document_rows\nWHERE dataset_id LIKE '%' || $1 || '%';",
        "options": {
          "queryReplacement": "={{ $('Set File ID').item.json.file_id }}"
        }
      },
      "id": "2612df82-46a0-4a30-87fb-10e4bcd8fff5",
      "name": "Delete Old Data Records",
      "type": "n8n-nodes-base.postgres",
      "position": [
        5440,
        1136
      ],
      "typeVersion": 2.5,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "mode": "insert",
        "tableName": "documents_pg",
        "options": {}
      },
      "id": "134ec4ac-6895-462a-8342-3b4a43602a85",
      "name": "Postgres PGVector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "position": [
        7264,
        1248
      ],
      "typeVersion": 1,
      "credentials": {
        "postgres": {
          "id": "VLycSgO24mTZhGHI",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "model": "Qwen3-Embedding-8B",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1.2,
      "position": [
        7136,
        1520
      ],
      "id": "6e51dcb5-7af0-4641-a012-31d6d3370cb3",
      "name": "Embeddings OpenAI1",
      "credentials": {
        "openAiApi": {
          "id": "Xyj6iByncXj1pvGF",
          "name": "OpenAi account"
        }
      }
    }
  ],
  "pinData": {},
  "connections": {
    "Postgres Chat Memory1": {
      "ai_memory": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields1": {
      "main": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook1": {
      "main": [
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RAG AI Agent1": {
      "main": [
        [
          {
            "node": "Respond to Webhook1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Documents1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get File Contents1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Query Document Rows1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Ollama (Change Base URL)1": {
      "ai_languageModel": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Postgres PGVector Store3": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Postgres PGVector Store3",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Postgres PGVector Store",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Extract Document Text": {
      "main": [
        [
          {
            "node": "Postgres PGVector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set File ID": {
      "main": [
        [
          {
            "node": "Delete Old Doc Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract PDF Text": {
      "main": [
        [
          {
            "node": "Postgres PGVector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Summarize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summarize": {
      "main": [
        [
          {
            "node": "Set Schema",
            "type": "main",
            "index": 0
          },
          {
            "node": "Postgres PGVector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Extract PDF Text",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract from Excel",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract from CSV",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract Document Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from Excel": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          },
          {
            "node": "Insert Table Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Schema": {
      "main": [
        [
          {
            "node": "Update Schema for Document Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from CSV": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          },
          {
            "node": "Insert Table Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Set File ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Document Metadata": {
      "main": [
        [
          {
            "node": "Read/Write Files from Disk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read/Write Files from Disk": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recursive Character Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Default Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Doc Records": {
      "main": [
        [
          {
            "node": "Delete Old Data Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Data Records": {
      "main": [
        [
          {
            "node": "Insert Document Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres PGVector Store": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Local File Trigger": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Postgres PGVector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "versionId": "8c8466aa-9515-4516-a298-ef724f5eaf8b",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "214e30d013b988176711bf23d9e855729e1cb4cbcfe4b069d2c4b88983c044d5"
  },
  "id": "nkBpaiPa_W1G0zUi3HeqR",
  "tags": []
}