{ "updatedAt": "2026-05-07T00:48:49.355Z", "createdAt": "2026-05-07T00:48:49.355Z", "id": "4YKnRQ9rOiQCeYEU", "name": "Paperless \u2192 RAG v1.0", "description": "Disabled 2026-05-24 after PD Ollama/LiteLLM hammering destabilized PlausibleDeniability. Needs redesign before re-enable.", "active": false, "isArchived": false, "nodes": [ { "parameters": { "httpMethod": "POST", "path": "paperless/rag-ingest", "options": {} }, "id": "a86d7025-bbf0-4c1b-a59c-ad254ddc913e", "name": "Paperless RAG Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 2, "position": [ 0, 0 ], "webhookId": "f2eccecb-9935-425b-be6a-f57fe4473f34" }, { "parameters": { "jsCode": "const data = $input.first().json;\nconst body = data.body || data;\n\nlet docId = body.document_id || body.id || body.doc_id || body.pk;\n\nif (!docId || typeof docId === 'string' && docId.includes('{')) {\n docId = null;\n}\n\nreturn [{ json: { docId } }];" }, "id": "8f6af849-bdd9-466e-af81-84d057fd7ca1", "name": "Extract Document ID", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 224, 0 ] }, { "parameters": { "url": "=https://paperless.paccoco.com/api/documents/{{ $json.docId ? $json.docId + '/' : '?ordering=-added&page_size=1' }}", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "Token 4fb34ba35b4ab76a0715e8c56faf00a31de4fb5d" } ] }, "options": {} }, "id": "0b53d951-40cd-4ef0-ab81-3dea73f8b1d7", "name": "Fetch Document", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 448, 0 ] }, { "parameters": { "jsCode": "const response = $input.first().json;\nconst doc = response.results ? response.results[0] : response;\n\nif (!doc || !doc.id) {\n throw new Error('No document found in response');\n}\n\nconst content = doc.content || '';\nconst title = doc.title || 'Untitled';\nconst correspondent = doc.correspondent_name || 'Unknown';\nconst created = doc.created || new Date().toISOString();\nconst docType = doc.document_type_name || 'unknown';\nconst tags = (doc.tags || []).join(', ');\n\n// Build rich text for RAG with metadata context\nconst ragText = `Document: ${title}\\nCorrespondent: ${correspondent}\\nType: ${docType}\\nTags: ${tags}\\nDate: ${created}\\n\\n${content}`;\n\nreturn [{\n json: {\n documentId: doc.id,\n title,\n ragText,\n source: `paperless-doc-${doc.id}`,\n metadata: {\n paperless_id: doc.id,\n title,\n correspondent,\n document_type: docType,\n created\n }\n }\n}];" }, "id": "e3d506bc-1677-4825-b3d3-f6187156da22", "name": "Prepare RAG Text", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 672, 0 ] }, { "parameters": { "jsCode": "// Split text into chunks for embedding\nconst input = $input.first().json;\nconst text = input.ragText || '';\nconst source = input.source;\nconst metadata = input.metadata;\n\nconst CHUNK_SIZE = 500;\nconst OVERLAP = 50;\n\nconst chunks = [];\nconst sentences = text.split(/(?<=[.!?])\\s+/);\nlet current = '';\n\nfor (const sentence of sentences) {\n if ((current + ' ' + sentence).length > CHUNK_SIZE && current.length > 0) {\n chunks.push(current.trim());\n const words = current.split(' ');\n current = words.slice(-OVERLAP).join(' ') + ' ' + sentence;\n } else {\n current = current ? current + ' ' + sentence : sentence;\n }\n}\nif (current.trim()) chunks.push(current.trim());\n\nreturn chunks.map((chunk, i) => ({\n json: {\n chunk,\n chunkIndex: i,\n totalChunks: chunks.length,\n source,\n metadata\n }\n}));" }, "id": "9a523501-3adb-41a3-b963-b6bb5adb25fe", "name": "Chunk Text", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 880, 0 ] }, { "parameters": { "method": "POST", "url": "http://10.5.30.6:11434/v1/embeddings", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={\n \"model\": \"nomic-embed-text\",\n \"input\": \"{{ $json.chunk }}\"\n}", "options": { "batching": { "batch": { "batchSize": 5, "batchInterval": 500 } } } }, "id": "0b631ea4-b11f-4533-960f-f5161ac798f3", "name": "Get Embedding", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1104, 0 ] }, { "parameters": { "jsCode": "const embeddingResponse = $input.first().json;\nconst chunkData = $('Chunk Text').item;\nconst embedding = embeddingResponse.data?.[0]?.embedding || [];\n\nconst pointId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = Math.random() * 16 | 0;\n return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);\n});\n\nreturn [{\n json: {\n id: pointId,\n vector: embedding,\n payload: {\n text: chunkData.json.chunk,\n source: chunkData.json.source,\n chunkIndex: chunkData.json.chunkIndex,\n totalChunks: chunkData.json.totalChunks,\n metadata: chunkData.json.metadata,\n ingested_at: new Date().toISOString()\n }\n }\n}];" }, "id": "ad9dc677-e3a2-464e-a82e-2aa4d8b9b042", "name": "Prepare Qdrant Point", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1328, 0 ] }, { "parameters": { "method": "PUT", "url": "http://10.5.30.6:6333/collections/knowledge_base/points", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={\n \"points\": [\n {\n \"id\": \"{{ $json.id }}\",\n \"vector\": {{ JSON.stringify($json.vector) }},\n \"payload\": {{ JSON.stringify($json.payload) }}\n }\n ]\n}", "options": {} }, "id": "e977b536-d470-4da0-a970-794a858e8aa9", "name": "Upsert to Qdrant", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1552, 0 ] }, { "parameters": { "jsCode": "const ragText = $('Prepare RAG Text').first().json;\nconst chunks = $('Chunk Text').first().json;\nreturn [{\n json: {\n title: '\ud83d\udcda Document Added to RAG',\n message: `${ragText.title} has been chunked and ingested into the knowledge base (${chunks.totalChunks || '?'} chunks)`,\n priority: 3\n }\n}];" }, "id": "fmt05-0001-0000-0000-000000000005", "name": "Format Gotify Message", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1520, 0 ] }, { "parameters": { "message": "={{ $json.message }}", "additionalFields": { "priority": "={{ $json.priority }}", "title": "={{ $json.title }}" }, "options": { "contentType": "text/plain" } }, "id": "ccdee208-b8f8-4ad4-a20c-94c4735d2e3d", "name": "Notify via Gotify", "type": "n8n-nodes-base.gotify", "typeVersion": 1, "position": [ 1760, 0 ], "credentials": { "gotifyApi": { "id": "SETUP_REQUIRED", "name": "Paperless RAG" } } } ], "connections": { "Paperless RAG Webhook": { "main": [ [ { "node": "Extract Document ID", "type": "main", "index": 0 } ] ] }, "Extract Document ID": { "main": [ [ { "node": "Fetch Document", "type": "main", "index": 0 } ] ] }, "Fetch Document": { "main": [ [ { "node": "Prepare RAG Text", "type": "main", "index": 0 } ] ] }, "Prepare RAG Text": { "main": [ [ { "node": "Chunk Text", "type": "main", "index": 0 } ] ] }, "Chunk Text": { "main": [ [ { "node": "Get Embedding", "type": "main", "index": 0 } ] ] }, "Get Embedding": { "main": [ [ { "node": "Prepare Qdrant Point", "type": "main", "index": 0 } ] ] }, "Prepare Qdrant Point": { "main": [ [ { "node": "Upsert to Qdrant", "type": "main", "index": 0 } ] ] }, "Upsert to Qdrant": { "main": [ [ { "node": "Format Gotify Message", "type": "main", "index": 0 } ] ] }, "Format Gotify Message": { "main": [ [ { "node": "Notify via Gotify", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "binaryMode": "separate" }, "staticData": null, "meta": null, "pinData": {}, "versionId": "3c20b423-8708-4540-8bf9-8db4880335a5", "activeVersionId": "3c20b423-8708-4540-8bf9-8db4880335a5", "versionCounter": 12, "triggerCount": 1, "tags": [ { "updatedAt": "2026-05-06T22:39:46.476Z", "createdAt": "2026-05-06T22:39:46.476Z", "id": "NxHjuO4MMd5kdPR7", "name": "paperless" }, { "updatedAt": "2026-05-06T22:39:33.284Z", "createdAt": "2026-05-06T22:39:33.284Z", "id": "7uuEyQrIlcuruZBk", "name": "rag" }, { "updatedAt": "2026-05-06T22:38:51.678Z", "createdAt": "2026-05-06T22:38:51.678Z", "id": "S9FxzVfHLsHmyzyt", "name": "ai" } ], "shared": [ { "updatedAt": "2026-05-07T00:48:49.355Z", "createdAt": "2026-05-07T00:48:49.355Z", "role": "workflow:owner", "workflowId": "4YKnRQ9rOiQCeYEU", "projectId": "dxCRnBdX5uJizCGa", "project": { "updatedAt": "2026-05-06T01:10:37.484Z", "createdAt": "2026-05-06T01:08:07.721Z", "id": "dxCRnBdX5uJizCGa", "name": "Wilfred Fizzlepoof ", "type": "personal", "icon": null, "description": null, "creatorId": "47b2227f-2fc2-4a08-bd35-ea157b92df0d" } } ], "versionMetadata": { "name": "Version 3c20b423", "description": "" } }