From 440678df1fd85f16593df197c83480b99cc55a6e Mon Sep 17 00:00:00 2001 From: gitea Date: Mon, 1 Jan 2001 00:00:00 +0000 Subject: [PATCH] Add paperless_ollama.json --- paperless_ollama.json | 260 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 paperless_ollama.json diff --git a/paperless_ollama.json b/paperless_ollama.json new file mode 100644 index 0000000..1525949 --- /dev/null +++ b/paperless_ollama.json @@ -0,0 +1,260 @@ +{ + "updatedAt": "2026-10-01T11:55:03.918Z", + "createdAt": "2026-10-01T08:16:25.450Z", + "id": "NljcXxbg9UqJVBEW", + "name": "paperless_ollama", + "active": true, + "isArchived": false, + "nodes": [ + { + "parameters": { + "workflowInputs": { + "values": [ + { + "name": "correspondents", + "type": "any" + }, + { + "name": "tags", + "type": "any" + }, + { + "name": "documents", + "type": "any" + }, + { + "name": "content", + "type": "any" + } + ] + } + }, + "type": "n8n-nodes-base.executeWorkflowTrigger", + "typeVersion": 1.1, + "position": [ + -256, + -368 + ], + "id": "4606e8a4-69c3-4ee1-b54e-a826590aa12e", + "name": "Input" + }, + { + "parameters": { + "jsCode": "const raw = $json.content || $json.text || \"\";\n\n// 1. Markdown entfernen & zuschneiden\nlet cleaned = raw.replace(/```json|```/g, '').trim();\n\n// 2. JSON-Bereich isolieren\nconst firstBrace = cleaned.indexOf('{');\nconst firstBracket = cleaned.indexOf('[');\nlet start = -1;\n\nif (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {\n start = firstBrace;\n} else if (firstBracket !== -1) {\n start = firstBracket;\n}\n\nif (start !== -1) {\n cleaned = cleaned.substring(start);\n}\n\n// 3. Parsen\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch (e) {\n // Notfall-Reparatur, falls schließende Klammer fehlte\n parsed = JSON.parse(cleaned + (cleaned.startsWith('[') ? ']' : '}'));\n}\n\n// 4. n8n-konformes Format zurückgeben\nif (Array.isArray(parsed)) {\n // Array -> Mehrere n8n Items\n return parsed.map(entry => ({\n json: typeof entry === 'object' && entry !== null ? entry : { value: entry }\n }));\n}\n\nif (typeof parsed === 'object' && parsed !== null) {\n // Normales Objekt -> Ein n8n Item\n return [{ json: parsed }];\n}\n\n// Primitiver Wert (String, Zahl etc.)\nreturn [{ json: { value: parsed } }];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 352, + -352 + ], + "id": "937e6c25-05c3-4e95-b8bf-76c310f80207", + "name": "Code in JavaScript", + "executeOnce": true + }, + { + "parameters": { + "modelId": { + "__rl": true, + "value": "ministral-3:3b", + "mode": "list", + "cachedResultName": "ministral-3:3b" + }, + "messages": { + "values": [ + { + "content": "=\n{{ (Array.isArray($json.correspondents) ?$json.correspondents : []).map(c => `[${c.paperless_id ?? c.id}] ${c.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.tags) ?$json.tags : []).map(t => `[${t.paperless_id ?? t.id}] ${t.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.documents) ?$json.documents : []).map(d => `[${d.paperless_id ?? d.id}] ${d.name}`).join(', ') }}\n\n\n\n{{ ($json.content || '').substring(0, 1200) }}\n" + } + ] + }, + "options": { + "system": "Klassifiziere den Dokumentenauszug anhand der bereitgestellten Listen.\n\nRegel für alle Entitäten:\n- Verwende die ID aus der jeweiligen Liste.\n- Falls kein passender Eintrag existiert: Setze die ID zwingend auf null und trage den neu erkannten Namen ein.\n- Tags dürfen mehrere Treffer oder ein leeres Array [] sein.\n\nAntworte ausschließlich mit reinem JSON (keine Markdown-Backticks, beginne direkt mit {):\n{\n \"Title\": \"Kurzer aussagekräftiger Dokumenttitel\",\n \"Korrespondent-ID\": number | null,\n \"Korrespondent\": \"string\",\n \"Dokumententyp-ID\": number | null,\n \"Dokumententyp\": \"string\",\n \"Tags\": [\n {\n \"Tag-ID\": number | null,\n \"Name\": \"string\"\n }\n ]\n}", + "temperature": 0, + "num_predict": 150, + "keep_alive": "5m", + "format": "json" + } + }, + "type": "@n8n/n8n-nodes-langchain.ollama", + "typeVersion": 1, + "position": [ + -32, + -368 + ], + "id": "b7823307-d92a-4ec4-89fe-fdb0b0e7141c", + "name": "Mistral", + "executeOnce": true, + "credentials": { + "ollamaApi": { + "id": "fgaZliEtIoej3jtn", + "name": "Ollama account" + } + } + } + ], + "connections": { + "Input": { + "main": [ + [ + { + "node": "Mistral", + "type": "main", + "index": 0 + } + ] + ] + }, + "Mistral": { + "main": [ + [ + { + "node": "Code in JavaScript", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "settings": { + "executionOrder": "v1", + "binaryMode": "separate" + }, + "staticData": null, + "meta": null, + "pinData": {}, + "versionId": "4bec14cf-b613-45e5-918b-73f02b6384d5", + "activeVersionId": "4bec14cf-b613-45e5-918b-73f02b6384d5", + "triggerCount": 0, + "shared": [ + { + "updatedAt": "2026-10-01T08:16:25.453Z", + "createdAt": "2026-10-01T08:16:25.453Z", + "role": "workflow:owner", + "workflowId": "NljcXxbg9UqJVBEW", + "projectId": "cSAaWNJydnksD5EB" + } + ], + "activeVersion": { + "updatedAt": "2026-10-01T11:55:06.000Z", + "createdAt": "2026-10-01T11:54:59.108Z", + "versionId": "4bec14cf-b613-45e5-918b-73f02b6384d5", + "workflowId": "NljcXxbg9UqJVBEW", + "nodes": [ + { + "parameters": { + "workflowInputs": { + "values": [ + { + "name": "correspondents", + "type": "any" + }, + { + "name": "tags", + "type": "any" + }, + { + "name": "documents", + "type": "any" + }, + { + "name": "content", + "type": "any" + } + ] + } + }, + "type": "n8n-nodes-base.executeWorkflowTrigger", + "typeVersion": 1.1, + "position": [ + -256, + -368 + ], + "id": "4606e8a4-69c3-4ee1-b54e-a826590aa12e", + "name": "Input" + }, + { + "parameters": { + "jsCode": "const raw = $json.content || $json.text || \"\";\n\n// 1. Markdown entfernen & zuschneiden\nlet cleaned = raw.replace(/```json|```/g, '').trim();\n\n// 2. JSON-Bereich isolieren\nconst firstBrace = cleaned.indexOf('{');\nconst firstBracket = cleaned.indexOf('[');\nlet start = -1;\n\nif (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {\n start = firstBrace;\n} else if (firstBracket !== -1) {\n start = firstBracket;\n}\n\nif (start !== -1) {\n cleaned = cleaned.substring(start);\n}\n\n// 3. Parsen\nlet parsed;\ntry {\n parsed = JSON.parse(cleaned);\n} catch (e) {\n // Notfall-Reparatur, falls schließende Klammer fehlte\n parsed = JSON.parse(cleaned + (cleaned.startsWith('[') ? ']' : '}'));\n}\n\n// 4. n8n-konformes Format zurückgeben\nif (Array.isArray(parsed)) {\n // Array -> Mehrere n8n Items\n return parsed.map(entry => ({\n json: typeof entry === 'object' && entry !== null ? entry : { value: entry }\n }));\n}\n\nif (typeof parsed === 'object' && parsed !== null) {\n // Normales Objekt -> Ein n8n Item\n return [{ json: parsed }];\n}\n\n// Primitiver Wert (String, Zahl etc.)\nreturn [{ json: { value: parsed } }];" + }, + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [ + 352, + -352 + ], + "id": "937e6c25-05c3-4e95-b8bf-76c310f80207", + "name": "Code in JavaScript", + "executeOnce": true + }, + { + "parameters": { + "modelId": { + "__rl": true, + "value": "ministral-3:3b", + "mode": "list", + "cachedResultName": "ministral-3:3b" + }, + "messages": { + "values": [ + { + "content": "=\n{{ (Array.isArray($json.correspondents) ?$json.correspondents : []).map(c => `[${c.paperless_id ?? c.id}] ${c.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.tags) ?$json.tags : []).map(t => `[${t.paperless_id ?? t.id}] ${t.name}`).join(', ') }}\n\n\n\n{{ (Array.isArray($json.documents) ?$json.documents : []).map(d => `[${d.paperless_id ?? d.id}] ${d.name}`).join(', ') }}\n\n\n\n{{ ($json.content || '').substring(0, 1200) }}\n" + } + ] + }, + "options": { + "system": "Klassifiziere den Dokumentenauszug anhand der bereitgestellten Listen.\n\nRegel für alle Entitäten:\n- Verwende die ID aus der jeweiligen Liste.\n- Falls kein passender Eintrag existiert: Setze die ID zwingend auf null und trage den neu erkannten Namen ein.\n- Tags dürfen mehrere Treffer oder ein leeres Array [] sein.\n\nAntworte ausschließlich mit reinem JSON (keine Markdown-Backticks, beginne direkt mit {):\n{\n \"Title\": \"Kurzer aussagekräftiger Dokumenttitel\",\n \"Korrespondent-ID\": number | null,\n \"Korrespondent\": \"string\",\n \"Dokumententyp-ID\": number | null,\n \"Dokumententyp\": \"string\",\n \"Tags\": [\n {\n \"Tag-ID\": number | null,\n \"Name\": \"string\"\n }\n ]\n}", + "temperature": 0, + "num_predict": 150, + "keep_alive": "5m", + "format": "json" + } + }, + "type": "@n8n/n8n-nodes-langchain.ollama", + "typeVersion": 1, + "position": [ + -32, + -368 + ], + "id": "b7823307-d92a-4ec4-89fe-fdb0b0e7141c", + "name": "Mistral", + "executeOnce": true, + "credentials": { + "ollamaApi": { + "id": "fgaZliEtIoej3jtn", + "name": "Ollama account" + } + } + } + ], + "connections": { + "Input": { + "main": [ + [ + { + "node": "Mistral", + "type": "main", + "index": 0 + } + ] + ] + }, + "Mistral": { + "main": [ + [ + { + "node": "Code in JavaScript", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "authors": "Prasanna Ranjan", + "name": "Version 4bec14cf", + "description": "", + "autosaved": false + }, + "tags": [] +} \ No newline at end of file