Chat With Your Data Room - RAG System

We've built a RAG system using which you can upload your data room documents in a google drive and start chatting with it. When you upload the files, our system extracts and saves the information. Then, the AI responds to your questions. This way you don't have to manually go through all the documents in a dataroom.

Workflow JSON

{
  "nodes": [
    {
      "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": "ef829fd9-6993-41ec-8085-4934e5bad509",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "typeVersion": 1,
      "position": [
        1008,
        1152
      ]
    },
    {
      "parameters": {
        "model": "text-embedding-3-small",
        "options": {}
      },
      "id": "1d5391c0-df0e-4a56-9fb1-3edbc6037723",
      "name": "Embeddings OpenAI1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1,
      "position": [
        832,
        1360
      ],
      "credentials": {
        "openAiApi": {
          "id": "lOvowxlyuIaEfYgD",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $('Set File ID').item.json.file_id }}",
          "mode": "id"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        }
      },
      "id": "82a75e42-c8cf-4d7a-bc79-99280bbecea4",
      "name": "Download File",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -544,
        832
      ],
      "executeOnce": true,
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "aLpYUFglLJY84JLr",
          "name": "Google Drive account"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "1XDO5Li8rL6ek7Z2oIYbc1hKbVto4SAtJ",
          "mode": "list",
          "cachedResultName": "DataRooms",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1XDO5Li8rL6ek7Z2oIYbc1hKbVto4SAtJ"
        },
        "event": "watchFolderUpdated"
      },
      "id": "09d78929-ff49-4134-b0f2-12bf87a4a1ce",
      "name": "File Created",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        -1952,
        624
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "aLpYUFglLJY84JLr",
          "name": "Google Drive account"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "1XDO5Li8rL6ek7Z2oIYbc1hKbVto4SAtJ",
          "mode": "list",
          "cachedResultName": "DataRooms",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1XDO5Li8rL6ek7Z2oIYbc1hKbVto4SAtJ"
        },
        "event": "fileUpdated",
        "options": {}
      },
      "id": "5d01de5b-9292-4596-b413-e7f211d1c45f",
      "name": "File Updated",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        -1680,
        832
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "aLpYUFglLJY84JLr",
          "name": "Google Drive account"
        }
      }
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "id": "da8410cd-b5b4-432f-9d3f-698c03ad9c21",
      "name": "Extract Document Text",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        208,
        1152
      ],
      "alwaysOutputData": true
    },
    {
      "parameters": {},
      "id": "929da278-5ffe-4c51-9b94-288570ffaaa8",
      "name": "Postgres Chat Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1,
      "position": [
        -592,
        384
      ],
      "notesInFlow": false,
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "operation": "delete",
        "tableId": "documents",
        "filterType": "string",
        "filterString": "=metadata->>file_id=like.*{{ $json.file_id }}*"
      },
      "id": "ce07afc2-c607-4e99-bf53-82e5887c32af",
      "name": "Delete Old Doc Rows",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -1120,
        832
      ],
      "alwaysOutputData": true,
      "credentials": {
        "supabaseApi": {
          "id": "s093zeqVjpOjQJwy",
          "name": "DataRoom System"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "10646eae-ae46-4327-a4dc-9987c2d76173",
              "name": "file_id",
              "value": "={{ $json.id }}",
              "type": "string"
            },
            {
              "id": "f4536df5-d0b1-4392-bf17-b8137fb31a44",
              "name": "file_type",
              "value": "={{ $json.mimeType }}",
              "type": "string"
            },
            {
              "id": "77d782de-169d-4a46-8a8e-a3831c04d90f",
              "name": "file_title",
              "value": "={{ $json.name }}",
              "type": "string"
            },
            {
              "id": "9bde4d7f-e4f3-4ebd-9338-dce1350f9eab",
              "name": "file_url",
              "value": "={{ $json.webViewLink }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "e94e120d-bad8-403a-ab6c-93daa9beb97a",
      "name": "Set File ID",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -1312,
        832
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "7a3051c2-3c78-46bc-aede-a8e6a5eb8d61",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -192,
        64
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9a9a245e-f1a1-4282-bb02-a81ffe629f0f",
              "name": "chatInput",
              "value": "={{ $json?.chatInput || $json.body.chatInput }}",
              "type": "string"
            },
            {
              "id": "b80831d8-c653-4203-8706-adedfdb98f77",
              "name": "sessionId",
              "value": "={{ $json?.sessionId || $json.body.sessionId}}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "02b299d1-abf0-4a6a-b069-4ed160db4129",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -736,
        144
      ]
    },
    {
      "parameters": {
        "public": true,
        "options": {}
      },
      "id": "000127e9-8007-4d87-ae99-f5474c3312a1",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.1,
      "position": [
        -1104,
        144
      ],
      "webhookId": "e104e40e-6134-4825-a6f0-8a646d882662"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "bf4dd093-bb02-472c-9454-7ab9af97bd1d",
        "authentication": "headerAuth",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "38027289-8744-4e05-b5d3-11c5c7f347ff",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1104,
        352
      ],
      "webhookId": "bf4dd093-bb02-472c-9454-7ab9af97bd1d",
      "credentials": {
        "httpHeaderAuth": {
          "id": "SOhBbZ8NzQjXRnok",
          "name": "Header Auth account"
        }
      }
    },
    {
      "parameters": {
        "operation": "pdf",
        "options": {}
      },
      "id": "a1564185-aab9-44c4-861e-e43c51c3b696",
      "name": "Extract PDF Text",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        208,
        592
      ]
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "id": "368cfc1b-c279-4f84-a5e1-57b37325aca6",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        272,
        768
      ]
    },
    {
      "parameters": {},
      "id": "c9f9668b-4420-45a1-a282-4eb725c3efc1",
      "name": "Character Text Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
      "typeVersion": 1,
      "position": [
        1056,
        1280
      ]
    },
    {
      "parameters": {
        "fieldsToSummarize": {
          "values": [
            {
              "aggregation": "concatenate",
              "field": "data"
            }
          ]
        },
        "options": {}
      },
      "id": "7d2eeec0-c649-4c9a-b2ba-1f1aba10efde",
      "name": "Summarize",
      "type": "n8n-nodes-base.summarize",
      "typeVersion": 1,
      "position": [
        448,
        848
      ]
    },
    {
      "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 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.\n\nNever output answers in Devanagari script. If the user asks a question in Hin-glish, answer in hinglish. "
        }
      },
      "id": "05e329e5-8aec-4e39-9b3c-6f0c51f9ea2d",
      "name": "RAG AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.6,
      "position": [
        -528,
        144
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/pdf",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "d8550b74-d706-4e04-95b6-ea65dc8ae217"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "id": "2ae7faa7-a936-4621-a680-60c512163034",
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "id": "fc193b06-363b-4699-a97d-e5a850138b0e",
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "=application/vnd.google-apps.spreadsheet",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "id": "b69f5605-0179-4b02-9a32-e34bb085f82d",
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/vnd.google-apps.document",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "none"
        }
      },
      "id": "9dcf7176-bb35-4678-a0a4-13862ba99030",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        -352,
        800
      ]
    },
    {
      "parameters": {
        "mode": "insert",
        "tableName": {
          "__rl": true,
          "value": "documents",
          "mode": "list",
          "cachedResultName": "documents"
        },
        "options": {
          "queryName": "match_documents"
        }
      },
      "id": "1bff7ecf-b0a0-4f22-a626-be23dcf9cbe9",
      "name": "Insert into Supabase Vectorstore",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1,
      "position": [
        928,
        928
      ],
      "credentials": {
        "supabaseApi": {
          "id": "s093zeqVjpOjQJwy",
          "name": "DataRoom System"
        }
      }
    },
    {
      "parameters": {
        "operation": "xlsx",
        "options": {}
      },
      "id": "4cb9d78d-962a-408c-9983-c9a2300e2733",
      "name": "Extract from Excel",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        16,
        832
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "f422e2e0-381c-46ea-8f38-3f58c501d8b9",
              "name": "schema",
              "value": "={{ $('Extract from Excel').isExecuted ? $('Extract from Excel').first().json.keys().toJsonString() : $('Extract from CSV').first().json.keys().toJsonString() }}",
              "type": "string"
            },
            {
              "id": "bb07c71e-5b60-4795-864c-cc3845b6bc46",
              "name": "data",
              "value": "={{ $json.concatenated_data }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        880,
        704
      ],
      "id": "027c43d0-afc6-4115-aebe-2e4b675090a9",
      "name": "Set Schema"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "CREATE TABLE document_metadata (\n    id TEXT PRIMARY KEY,\n    title TEXT,\n    url TEXT,\n    created_at TIMESTAMP DEFAULT NOW(),\n    schema TEXT\n);",
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -1888,
        176
      ],
      "id": "007eddb3-b5e3-46d8-aa85-fc29bc4e5674",
      "name": "Create Document Metadata Table",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "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": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -1648,
        176
      ],
      "id": "fbe70253-9da5-4991-9db4-a39a37d22b57",
      "name": "Create Document Rows Table (for Tabular Data)",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "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,
          "value": "document_metadata",
          "mode": "list",
          "cachedResultName": "document_metadata"
        },
        "returnAll": true,
        "options": {}
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        -464,
        368
      ],
      "id": "5b0773a8-623d-4bb1-89eb-a21c0810a89b",
      "name": "List Documents",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Given a file ID, fetches the text from the document.",
        "operation": "executeQuery",
        "query": "SELECT \n    string_agg(content, ' ') as document_text\nFROM documents\n  WHERE metadata->>'file_id' = $1\nGROUP BY metadata->>'file_id';",
        "options": {
          "queryReplacement": "={{ $fromAI('file_id') }}"
        }
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        -320,
        368
      ],
      "id": "4f978236-cdbe-4fe0-9880-72b181be9f13",
      "name": "Get File Contents",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "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 you are querying. dataset_id is the file_id 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 = '123';\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 = '123'\nGROUP BY row_data->>'category';",
        "operation": "executeQuery",
        "query": "{{ $fromAI('sql_query') }}",
        "options": {}
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        -160,
        368
      ],
      "id": "57df86af-445f-4f15-a8b5-92b6a2760be0",
      "name": "Query Document Rows",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "documents",
        "toolDescription": "Use RAG to look up information in the knowledgebase.",
        "tableName": {
          "__rl": true,
          "value": "documents",
          "mode": "list",
          "cachedResultName": "documents"
        },
        "options": {
          "queryName": "match_documents"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1,
      "position": [
        160,
        144
      ],
      "id": "2ee042d5-28fc-4396-b63e-cd2a797d43ed",
      "name": "Supabase Vector Store1",
      "credentials": {
        "supabaseApi": {
          "id": "s093zeqVjpOjQJwy",
          "name": "DataRoom System"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1.2,
      "position": [
        240,
        336
      ],
      "id": "e21eeed9-e4ca-4a7d-a9bf-d1a2d4687b18",
      "name": "Embeddings OpenAI2",
      "disabled": true
    },
    {
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -1504,
        672
      ],
      "id": "17653084-602d-408c-803f-1d641ffccabd",
      "name": "Loop Over Items"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "-- Enable the pgvector extension to work with embedding vectors\ncreate extension vector;\n\n-- Create a table to store your documents\ncreate table documents (\n  id bigserial primary key,\n  content text, -- corresponds to Document.pageContent\n  metadata jsonb, -- corresponds to Document.metadata\n  embedding vector(768) -- 1536 works for OpenAI embeddings, change if needed\n);\n\n-- Create a function to search for documents\ncreate function match_documents (\n  query_embedding vector(768),\n  match_count int default null,\n  filter jsonb DEFAULT '{}'\n) returns table (\n  id bigint,\n  content text,\n  metadata jsonb,\n  similarity float\n)\nlanguage plpgsql\nas $$\n#variable_conflict use_column\nbegin\n  return query\n  select\n    id,\n    content,\n    metadata,\n    1 - (documents.embedding <=> query_embedding) as similarity\n  from documents\n  where metadata @> filter\n  order by documents.embedding <=> query_embedding\n  limit match_count;\nend;\n$$;",
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -2160,
        176
      ],
      "id": "00043cc4-d359-4da6-b9c2-d5b5d26d053f",
      "name": "Create Documents Table and Match Function",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "operation": "delete",
        "tableId": "document_rows",
        "filters": {
          "conditions": [
            {
              "keyName": "dataset_id",
              "condition": "eq",
              "keyValue": "={{ $('Set File ID').item.json.file_id }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -928,
        832
      ],
      "id": "924ec6d0-3a1e-46d5-a9f5-ad4b924d7d21",
      "name": "Delete Old Data Rows",
      "alwaysOutputData": true,
      "executeOnce": true,
      "credentials": {
        "supabaseApi": {
          "id": "s093zeqVjpOjQJwy",
          "name": "DataRoom System"
        }
      }
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_metadata",
          "mode": "list",
          "cachedResultName": "document_metadata"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $('Set File ID').item.json.file_id }}",
            "title": "={{ $('Set File ID').item.json.file_title }}",
            "url": "={{ $('Set File ID').item.json.file_url }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": true,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "title",
              "displayName": "title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "url",
              "displayName": "url",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "schema",
              "displayName": "schema",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -720,
        832
      ],
      "id": "ceda24e3-f1a0-4347-b13d-4a41a6bcf02c",
      "name": "Insert Document Metadata",
      "executeOnce": true,
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_rows",
          "mode": "list",
          "cachedResultName": "document_rows"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "dataset_id": "={{ $('Set File ID').item.json.file_id }}",
            "row_data": "={{ $json.toJsonString().replaceAll(/'/g, \"''\") }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "dataset_id",
              "displayName": "dataset_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "row_data",
              "displayName": "row_data",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "object",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        272,
        944
      ],
      "id": "f43150e0-1512-412c-88d1-dd11ea7a085d",
      "name": "Insert Table Rows",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_metadata",
          "mode": "list",
          "cachedResultName": "document_metadata"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $('Set File ID').item.json.file_id }}",
            "schema": "={{ $json.schema }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": true,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "title",
              "displayName": "title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": true
            },
            {
              "id": "url",
              "displayName": "url",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": true
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "schema",
              "displayName": "schema",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        1104,
        704
      ],
      "id": "0c916ba2-84d5-4973-8347-9d67fda1a2bf",
      "name": "Update Schema for Document Metadata",
      "credentials": {
        "postgres": {
          "id": "MAzz5L2QNWYBFAIb",
          "name": "Postgres account"
        }
      }
    },
    {
      "parameters": {
        "model": "deepseek/deepseek-chat-v3.1",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        -736,
        384
      ],
      "id": "71b6ee9e-7a41-47d5-bb75-94f043976908",
      "name": "OpenRouter Chat Model",
      "credentials": {
        "openRouterApi": {
          "id": "fPGAgoXwik56AiIL",
          "name": "OpenRouter account"
        }
      }
    },
    {
      "parameters": {
        "model": "nomic-embed-text:latest"
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
      "typeVersion": 1,
      "position": [
        96,
        352
      ],
      "id": "8e6ccc45-6f36-492a-b12d-2b892bbcc8d0",
      "name": "Embeddings Ollama",
      "credentials": {
        "ollamaApi": {
          "id": "LdKRmOBPaRIyEyDi",
          "name": "Ollama account"
        }
      }
    },
    {
      "parameters": {
        "model": "nomic-embed-text:latest"
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
      "typeVersion": 1,
      "position": [
        832,
        1200
      ],
      "id": "ed3da90f-b7f6-42ff-ac3b-39d30cbf4b49",
      "name": "Embeddings Ollama1",
      "credentials": {
        "ollamaApi": {
          "id": "LdKRmOBPaRIyEyDi",
          "name": "Ollama account"
        }
      }
    },
    {
      "parameters": {
        "resource": "fileFolder",
        "returnAll": true,
        "filter": {
          "folderId": {
            "__rl": true,
            "value": "1XDO5Li8rL6ek7Z2oIYbc1hKbVto4SAtJ",
            "mode": "list",
            "cachedResultName": "DataRooms",
            "cachedResultUrl": "https://drive.google.com/drive/folders/1XDO5Li8rL6ek7Z2oIYbc1hKbVto4SAtJ"
          }
        },
        "options": {
          "fields": [
            "*"
          ]
        }
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -1744,
        624
      ],
      "id": "a6c01c1d-5d23-4fea-81ee-b88d84aa164c",
      "name": "Search files and folders",
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "aLpYUFglLJY84JLr",
          "name": "Google Drive account"
        }
      }
    }
  ],
  "connections": {
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        []
      ]
    },
    "Download File": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Created": {
      "main": [
        [
          {
            "node": "Search files and folders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Updated": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Document Text": {
      "main": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Doc Rows": {
      "main": [
        [
          {
            "node": "Delete Old Data Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set File ID": {
      "main": [
        [
          {
            "node": "Delete Old Doc Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "RAG AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract PDF Text": {
      "main": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Summarize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Character Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Default Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Summarize": {
      "main": [
        [
          {
            "node": "Set Schema",
            "type": "main",
            "index": 0
          },
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RAG AI Agent": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "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 Excel",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract Document Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert into Supabase Vectorstore": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "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
          }
        ]
      ]
    },
    "Create Document Metadata Table": {
      "main": [
        [
          {
            "node": "Create Document Rows Table (for Tabular Data)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Documents": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get File Contents": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Query Document Rows": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI2": {
      "ai_embedding": [
        []
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Set File ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Documents Table and Match Function": {
      "main": [
        [
          {
            "node": "Create Document Metadata Table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Data Rows": {
      "main": [
        [
          {
            "node": "Insert Document Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Document Metadata": {
      "main": [
        [
          {
            "node": "Download File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings Ollama": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings Ollama1": {
      "ai_embedding": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Search files and folders": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "meta": {
    "instanceId": "68e38a4d16f6bb0fc4dc0d12c182b0537e5cd43d16c8c06d03fb68dbc38c8ff4"
  }
}