{
  "nodes": [
    {
      "id": "dcd42ca2-abff-41a7-b392-6e0de1b6999f",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1320,
        2380
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "8eb7679b-eec3-40e4-afb0-2bd7f544ec9e",
      "name": "Extract from PDF",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        2500,
        2340
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "cf0a457c-2555-4375-86b8-bbb676d1ee82",
      "name": "Extract from CSV",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        2500,
        2540
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "21b6bae8-a26e-47e5-8b14-ba43bf8f9295",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        4580,
        2540
      ],
      "parameters": {
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "file_id",
                "value": "={{ $('Set File ID').first().json.file_id}}"
              },
              {
                "name": "title",
                "value": "={{ $('Create Metadata Title & Description').item.json.output.title }}"
              },
              {
                "name": "description",
                "value": "={{ $('Create Metadata Title & Description').item.json.output.description }}"
              }
            ]
          }
        },
        "jsonData": "={{ $json.concatenated_text }}",
        "jsonMode": "expressionData"
      },
      "typeVersion": 1
    },
    {
      "id": "12ee63ca-5662-400f-a0a0-b9e12346091d",
      "name": "Google Drive Trigger File Created",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        1060,
        2380
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "url",
          "value": "https://drive.google.com/drive/u/0/folders/1B-Wl-ktVFbTmX685DB978jNvs9Ihnxiv"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "915d117f-69aa-4f56-9051-cb3d3ba862c2",
      "name": "Character Text Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
      "position": [
        4680,
        2720
      ],
      "parameters": {
        "separator": "###SPLIT###"
      },
      "typeVersion": 1
    },
    {
      "id": "741ee49a-04d3-47e5-89cc-2a8f50a94ad8",
      "name": "Set File ID",
      "type": "n8n-nodes-base.set",
      "position": [
        1580,
        2400
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0144a9a7-6e73-46c4-979f-838ad5c62b89",
              "name": "file_id",
              "type": "string",
              "value": "={{ $json.id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "94f4b238-7365-4fd0-b7fd-1cdc9c5bbc00",
      "name": "Download FIle",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1820,
        2400
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set File ID').item.json.file_id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "application/pdf"
            }
          }
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "c3ed78a0-7ff3-40f0-a4be-038d4908d0bc",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        2100,
        2400
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "application/pdf",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "e959d5a8-d311-4a29-b400-7c07468a72fe",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $binary.data.mimeType }}",
                    "rightValue": "application/pdf"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "text/csv",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "d5ae6f2d-e62d-4e08-aa06-629e6dfa7ee8",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $binary.data.mimeType }}",
                    "rightValue": "text/csv"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "c8c85b4c-b568-4e44-96dc-b6feabc463f5",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        3320,
        2620
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"title\": \"Test Title (Replace it with real title\",\n    \"description\":\"Test Description (Replace it with real description)\"\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "5d448edf-f219-4edb-90a3-a5b64bd2239a",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        4100,
        2500
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-1.5-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5a399f9f-df56-4c0f-913a-8f02c15bf334",
      "name": "Process Context",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        3940,
        2340
      ],
      "parameters": {
        "text": "=<document> \n{{ $('Document Data').first().json.data }}\n</document> \n\nHere is the chunk we want to situate within the overall document:\n\n<chunk> \n{{ $json.chunk }}\n</chunk> \n\nPlease:\n- Provide a short and succinct **context** to situate this chunk within the document for improved search retrieval.\n- Return the **original chunk** exactly as provided unless a correction is necessary.\n- If the chunk contains an **incomplete number, percentage, or entity**, correct it using the full document.\n- If part of a **sentence is cut off**, reconstruct the missing words only if necessary for clarity.\n- If the chunk is part of a table, include the complete table entry to maintain data integrity\n- Do not add any additional explanations or formatting beyond the required output.\n\nFill in the following format:\n[succinct context] : [original chunk or corrected version if necessary]\n\nYour response should contain only the text that replaces these placeholders, without including the placeholder labels themselves.",
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "04138472-84dc-47d6-8909-7ff9404613b1",
      "name": "Document Data",
      "type": "n8n-nodes-base.set",
      "position": [
        2760,
        2340
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"data\":  {{ JSON.stringify($json.text) }}\n} "
      },
      "typeVersion": 3.4
    },
    {
      "id": "aec980bc-6f3f-43b9-bd11-bd1fd07c9f5c",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        3560,
        2340
      ],
      "parameters": {
        "options": {
          "destinationFieldName": "chunk"
        },
        "fieldToSplitOut": "chunks"
      },
      "typeVersion": 1
    },
    {
      "id": "ca2fb84a-db88-488c-a240-3a2e4ddd40af",
      "name": "Limit",
      "type": "n8n-nodes-base.limit",
      "position": [
        3740,
        2340
      ],
      "parameters": {
        "maxItems": 20
      },
      "typeVersion": 1
    },
    {
      "id": "fc015ac7-c474-40d0-91fd-9502d0bd4b25",
      "name": "Summarize",
      "type": "n8n-nodes-base.summarize",
      "position": [
        4260,
        2340
      ],
      "parameters": {
        "options": {},
        "fieldsToSummarize": {
          "values": [
            {
              "field": "text",
              "separateBy": "other",
              "aggregation": "concatenate",
              "customSeparator": "###SPLIT###"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "0873b091-e714-41d6-b23e-1a3222061806",
      "name": "Embeddings OpenAI",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        4460,
        2540
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5f4ccb20-f17b-41b6-9700-06cccfd10fee",
      "name": "Add Data to Supabase Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        4460,
        2340
      ],
      "parameters": {
        "mode": "insert",
        "options": {},
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "documents",
          "cachedResultName": "documents"
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "1f99f8b9-3335-4c82-b04d-873637914605",
      "name": "Google Gemini Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        3120,
        2640
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-1.5-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ecb8a6de-2937-4658-b063-be11253350ed",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        980,
        2200
      ],
      "parameters": {
        "color": 4,
        "width": 1960,
        "height": 560,
        "content": "## \ud83d\udcc1 Data Processing from Google Drive\nAutomatically monitors your Google Drive folder and processes new files. When you upload a PDF, CSV, or Google Doc, this section downloads the file, extracts all the text content, and prepares it for AI analysis. Think of it as your automatic document reader that never sleeps."
      },
      "typeVersion": 1
    },
    {
      "id": "52e22d2e-4633-484b-bd00-d6baa7659366",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3000,
        2200
      ],
      "parameters": {
        "color": 4,
        "width": 1940,
        "height": 700,
        "content": "## \ud83e\udde0 RAG Data Upload Pipeline\nTakes your extracted document text and makes it AI-ready. It creates smart summaries, breaks documents into digestible chunks, adds context to each piece, and stores everything in a searchable database. This is where your documents become \"AI-searchable\" knowledge that can answer questions."
      },
      "typeVersion": 1
    },
    {
      "id": "935fb434-2404-42f2-9a46-0830a1dfe01c",
      "name": "Create Metadata Title & Description",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        3060,
        2340
      ],
      "parameters": {
        "text": "=Create metadata title and metadata description based on the document specified below (below ##Document). Metadata title and metadata description will be used to seperate data in vector DB that will be used for RAG.\n\n##Document\n{{ $('Document Data').item.json.data }}",
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.6
    },
    {
      "id": "803601cb-5289-493a-8475-4fb99817c513",
      "name": "Split into chunks",
      "type": "n8n-nodes-base.code",
      "position": [
        3400,
        2340
      ],
      "parameters": {
        "jsCode": "const chunkSize = 1000;\nconst chunkOverlap = 200;\n//const text = $node[\"ABC\"].json.data.replace(/\\n/, '');\nconst text = $items(\"Document Data\")[0].json.data.replace(/\\n/, '');\n\nconst chunks = [];\nlet remainingText = text;\n\nwhile (remainingText.length > 0) {\n    let splitPoint;\n\n    // Try splitting at paragraph level first\n    splitPoint = remainingText.lastIndexOf(\"\\n\\n\", chunkSize);\n    \n    // If no paragraph split, try splitting at sentence level\n    if (splitPoint === -1) {\n        splitPoint = remainingText.lastIndexOf(\". \", chunkSize);\n    }\n\n    // If no sentence split, try splitting at word level\n    if (splitPoint === -1) {\n        splitPoint = remainingText.lastIndexOf(\" \", chunkSize);\n    }\n\n    // If still no split point, force cut at chunkSize\n    if (splitPoint === -1 || splitPoint < chunkSize * 0.5) {  \n        splitPoint = chunkSize; // Hard split if no good split point\n    }\n\n    // Extract chunk and adjust remaining text with overlap\n    let chunk = remainingText.substring(0, splitPoint).trim();\n    chunks.push(chunk);\n\n    // Move the pointer forward while keeping the overlap\n    remainingText = remainingText.substring(Math.max(0, splitPoint - chunkOverlap)).trim();\n\n    // Break if remaining text is too small to form another chunk\n    if (remainingText.length < chunkSize * 0.2) {\n        chunks.push(remainingText);\n        break;\n    }\n}\n\nreturn { chunks };"
      },
      "typeVersion": 2
    },
    {
      "id": "3b6c1bab-b11f-499b-8fba-b2b12449aadc",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2680,
        1720
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4dcc7e04-d939-47de-9b37-41abc4c9c2c3",
      "name": "Supabase Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        2980,
        1760
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "topK": 20,
        "options": {},
        "toolName": "documents",
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "documents",
          "cachedResultName": "documents"
        },
        "toolDescription": "Work with your data in Supabase Vector Store"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "21016db6-a271-4306-ac0d-941a2c459322",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2720,
        1500
      ],
      "parameters": {
        "text": "=User Input:\n{{ $json.chatInput }}",
        "options": {
          "systemMessage": "=You're an internal company knowledge assistants. Your job is to answer questions using the files in the Vector Database. Here's how to do it:\n\nCheck Vector Database First\n- Search for similar test chunks using RAG.\n- If you find matches, use them to answer the question. \n- If you find relevant matches and need additional context to support the answer, prioritize retrieving it from documents that share the same metadata \"file_id\" & \"title\" before exploring other sources.\"\n\nNo Answer Found?\n- Clearly say: \"I couldn't find this in the databases\"\n- Never guess or invent answers.\n\nExample Response:\n\"Netflix grew revenue in Streaming services by 20% in 2024.\""
        },
        "promptType": "define"
      },
      "typeVersion": 1.8
    },
    {
      "id": "0f5e7c7c-8adf-4688-92cd-f0195e972346",
      "name": "Embeddings OpenAI1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        3060,
        1940
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "525f1628-a913-400e-895e-d009be257293",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        2480,
        1500
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "aea2befa-20ce-4f27-999b-95c682f70f50",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        2840,
        1760
      ],
      "parameters": {
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "465f36f8-5d33-4580-867c-cd854f16a871",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2300,
        1380
      ],
      "parameters": {
        "color": 4,
        "width": 1180,
        "height": 760,
        "content": "## AI Chat Agent - Chat with your documents stored in Supabase Vector Store\nour personal AI assistant that can answer questions about all your uploaded documents. Ask anything in plain English - it searches through your document database, finds relevant information, and gives you accurate answers with source references. It remembers your conversation and never makes up information."
      },
      "typeVersion": 1
    },
    {
      "id": "f15e6542-dccf-457b-af0a-d2d6a9eab48f",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        1380
      ],
      "parameters": {
        "color": 5,
        "width": 460,
        "height": 320,
        "content": "## \ud83d\udcc4 AI-Powered RAG Document Processing & Chatbot with Google Drive, Supabase, OpenAI\n\n**What This Workflow Does:**\n- Watches a Google Drive folder for new documents\n- Extracts text from PDF/CSV files\n- Enhances the text using AI (Google Gemini)\n- Chunks and embeds the text using OpenAI\n- Stores vector data in Supabase for semantic search\n- Enables users to chat with documents using OpenAI"
      },
      "typeVersion": 1
    },
    {
      "id": "dfd4d156-8f0b-4a27-ac69-3578d1602722",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        300,
        2200
      ],
      "parameters": {
        "color": 5,
        "width": 660,
        "height": 1500,
        "content": "## \ud83d\udccb Data Processing & RAG Workflow\n\n### \ud83d\udcc1 Step 1: Google Drive Trigger  \nWatches a specific Google Drive folder for new file uploads. Triggers every minute.\n\n### \ud83d\udd01 Step 2: Loop Over Uploaded Files  \nEnsures each uploaded file is processed one-by-one to avoid bulk processing issues.\n\n### \ud83c\udd94 Step 3: Set File ID  \nExtracts and stores the Google Drive file ID for reference in later steps.\n\n### \ud83d\udce5 Step 4: Download File  \nDownloads the file (PDF, CSV, or Google Docs). Google Docs are auto-converted to PDF.\n\n### \ud83e\udded Step 5: File Type Switch  \nRoutes file based on type:\n- PDF \u2192 Go to PDF Text Extractor\n- CSV \u2192 Go to CSV Extractor\n\n### \ud83d\udcc4 Step 6A: Extract Text from PDF  \nExtracts raw text content from the PDF file.\n\n### \ud83d\udcca Step 6B: Extract Text from CSV  \nExtracts and formats CSV data into a readable string.\n\n### \ud83d\udce6 Step 7: Format Document Data  \nWraps extracted text into JSON: `{\"data\": \"text content\"}`.\n\n### \ud83e\udde0 Step 8: Generate Metadata (Gemini)  \nUses Gemini AI to create a document title and description.\n\n### \u2702\ufe0f Step 9: Split into Chunks  \nSplits the document text into 1000-character chunks with 200-character overlap, intelligently at paragraph/sentence/word level.\n\n### \ud83d\udd04 Step 10: Split Out Chunks  \nConverts array of chunks into individual workflow items.\n\n### \ud83d\udeab Step 11: Limit to 20 Chunks  \nLimits processing to first 20 chunks to control API and processing load.\n\n### \ud83e\udde0 Step 12: Enhance Chunk Context (Gemini)  \nEach chunk is enhanced for better clarity, continuity, and context using Gemini.\n\n### \ud83e\udde9 Step 13: Summarize  \nCombines enhanced chunks using `###SPLIT###` separator for further processing.\n\n### \ud83e\uddf7 Step 14: Re-Split Enhanced Chunks  \nSplits combined text back into chunks using `###SPLIT###` separator.\n\n### \ud83e\uddec Step 15: Generate Embeddings (OpenAI)  \nConverts text chunks into vector embeddings for semantic search.\n\n### \ud83d\uddc2\ufe0f Step 16: Add Metadata  \nEach chunk is wrapped with metadata (file ID, title, description) for vector DB.\n\n### \ud83e\udde0 Step 17: Store in Supabase Vector DB  \nStores embeddings in Supabase vector store for later semantic retrieval.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "122852a9-eb55-4af6-a959-f0a95a9b61c3",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2300,
        820
      ],
      "parameters": {
        "color": 5,
        "width": 1160,
        "height": 520,
        "content": "\n## SETUP REQUIRED  \n**Author:** [Billy Christi](https://n8n.io/creators/billy/)\n\n---\n\n### \ud83d\udcda Database: Supabase Table `documents`\n\nTo manage and store embeddings and metadata, we use a Supabase table with the following schema:\n\n```sql\nCREATE TABLE public.documents (\n  id bigserial PRIMARY KEY,         -- Unique identifier\n  content text,                     -- Textual content of the document\n  metadata jsonb,                   -- Additional metadata (e.g., title, source)\n  embedding vector                  -- Vector embeddings (for similarity search, etc.)\n);\n````\n### \ud83d\udd10 Required Credentials & Keys\n\u2705 **Google Drive Credential** \n\u2705 **Supabase API Key & Project URL** \n\u2705 **OpenAI API Key**\n\u2705 **Google Gemini API Key**\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "851bb367-bcc4-4444-9b01-21dd9666265f",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1600,
        1380
      ],
      "parameters": {
        "color": 5,
        "width": 660,
        "height": 760,
        "content": "\n## \ud83e\udd16 CHAT INTERFACE WORKFLOW\n\n### \ud83d\udcac Step 1: Chat Trigger  \nListens for user chat input (e.g., question about a document).\n\n### \ud83e\udde0 Step 2: Simple Memory  \nStores last 10 messages to maintain conversation context.\n\n### \ud83d\udd0d Step 3: Vector Search (Supabase)  \nSearches Supabase vector DB for relevant chunks related to the user's question.\n\n### \ud83e\uddec Step 4: Convert Question to Embedding  \nUses OpenAI to embed the question text for similarity search.\n\n### \ud83d\udde8\ufe0f Step 5: Generate Response (OpenAI GPT-4o-mini)  \nUses context + question to generate a natural language answer.\n\n### \ud83e\udde0 Step 6: AI Agent  \nFinal agent logic:\n- Searches vector DB first\n- Answers based on found chunks\n- Attributes response to correct document\n- Admits if answer not found (no hallucination)"
      },
      "typeVersion": 1
    },
    {
      "id": "7429d34b-af0f-476c-893f-285cfe8e28ba",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3640,
        2480
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 300,
        "content": "\ud83d\udccc **Understanding the Limit Node**\nThe **Limit Node** restricts the number of records or items processed in your workflow. This is especially useful for:\n\u2705 **Testing** your setup with a smaller dataset\n\u2705 **Controlling resource usage** during processing\n\n\ud83d\udca1 **You can**:\n* **Adjust the limit value** to suit your workflow's needs\n* **Remove the Limit Node** altogether to process all available data"
      },
      "typeVersion": 1
    },
    {
      "id": "c4ad1f43-43ff-4f19-8e68-915c5ffeeb37",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3520,
        1380
      ],
      "parameters": {
        "color": 4,
        "width": 380,
        "height": 760,
        "content": "# \ud83d\udc4b Hi, I\u2019m Billy\n![My Photo](https://i.ibb.co/Gvn63Bzc/Billy-Christi-AI-Automation.jpg)\nI help businesses build **n8n workflows** & **AI automation projects**.  \nNeed help with n8n or AI Automation projects? \nContact me and let\u2019s build your automation together.\n\n\ud83d\udce9 **Email:** billychartanto@gmail.com  \n\ud83e\udd1d **n8n Creator:** [n8n.io/creators/billy](https://n8n.io/creators/billy/)\n\ud83c\udf10 **My n8n Projects:** [billychristi.com/n8n](https://www.billychristi.com/n8n)  \n\n\n\n---\n\ud83d\udca1 Feel free to get in touch if you\u2019d like help on your next automation project or if you have any feedback or thoughts to share.\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Limit": {
      "main": [
        [
          {
            "node": "Process Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Extract from PDF",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract from CSV",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summarize": {
      "main": [
        [
          {
            "node": "Add Data to Supabase Vector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set File ID": {
      "main": [
        [
          {
            "node": "Download FIle",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Document Data": {
      "main": [
        [
          {
            "node": "Create Metadata Title & Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download FIle": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Set File ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Context": {
      "main": [
        [
          {
            "node": "Summarize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from CSV": {
      "main": [
        [
          {
            "node": "Document Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from PDF": {
      "main": [
        [
          {
            "node": "Document Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Add Data to Supabase Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Split into chunks": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Add Data to Supabase Vector Store",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Character Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Default Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Process Context",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Create Metadata Title & Description",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Create Metadata Title & Description",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive Trigger File Created": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Metadata Title & Description": {
      "main": [
        [
          {
            "node": "Split into chunks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}