{ "name": "Vector Centroid API", "tags": [], "nodes": [ { "id": "32a8aa56-aa7e-4c9e-a39e-f65234224bcf", "name": "Receive Vectors", "type": "n8n-nodes-base.webhook", "position": [ -440, 20 ], "parameters": { "httpMethod": "GET", "path": "vector-centroid-api", "responseMode": "responseNode", "options": {} }, "notesInFlow": true, "typeVersion": 2 }, { "id": "a020a49a-cc9f-49af-aa95-829d9d16da04", "name": "Extract & Parse Vectors", "type": "n8n-nodes-base.code", "position": [ 360, 20 ], "parameters": { "mode": "runOnceForEachItem", "jsCode": "const parse = function vectorRequest({ query }) {\n if (typeof query.vectors !== 'string' || !query.vectors) return { vectors: null, error: 'Invalid input: Expected an array of vectors.' };\n try {\n let nonFinite = false;\n const vectors = JSON.parse(query.vectors, (_key, value) => {\n if (typeof value === 'number' && !Number.isFinite(value)) nonFinite = true;\n return value;\n });\n if (nonFinite) return { vectors: null, error: 'Vectors must contain finite numbers.' };\n return { vectors, error: null };\n }\n catch { return { vectors: null, error: 'Invalid input: vectors must be valid JSON.' }; }\n}\n\nreturn {json:parse({query:$json.query})};" }, "typeVersion": 2 }, { "id": "2f328de6-4ef1-4aac-8838-d616637f4b88", "name": "Validate & Compute Centroid", "type": "n8n-nodes-base.code", "position": [ 960, 20 ], "parameters": { "mode": "runOnceForEachItem", "jsCode": "const calculate = function vectorCentroid({ vectors, error }) {\n const fail = (error) => ({ result: { error } });\n if (error) return fail(error);\n if (!Array.isArray(vectors) || vectors.length === 0) return fail('Invalid input: Expected an array of vectors.');\n if (!vectors.every(Array.isArray)) return fail('Each vector must be an array.');\n const dimension = vectors[0].length;\n if (!vectors.every((vector) => vector.length === dimension)) return fail('Vectors have inconsistent dimensions.');\n if (!vectors.every((vector) => vector.every((value) => typeof value === 'number' && Number.isFinite(value)))) return fail('Vectors must contain finite numbers.');\n const centroid = Array.from({ length: dimension }, (_, index) => {\n let scale = 0;\n for (const vector of vectors) scale = Math.max(scale, Math.abs(vector[index]));\n if (scale === 0) return 0;\n let sum = 0, correction = 0;\n for (const vector of vectors) {\n const adjusted = vector[index] / scale - correction;\n const next = sum + adjusted;\n correction = (next - sum) - adjusted;\n sum = next;\n }\n return (sum / vectors.length) * scale;\n });\n if (!centroid.every(Number.isFinite)) return fail('Centroid exceeds the finite numeric range.');\n return { result: { centroid } };\n}\n\nreturn {json:calculate($json).result};" }, "typeVersion": 2 }, { "id": "821bc173-3578-4cf2-9fd7-8ea9cba8dc3f", "name": "Return Centroid Response", "type": "n8n-nodes-base.respondToWebhook", "position": [ 1640, 20 ], "parameters": { "respondWith": "json", "responseBody": "={{ $json }}", "options": { "responseCode": 200 } }, "typeVersion": 1.1 }, { "id": "73964e7b-1217-422f-8078-09604fa2a3d7", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ 20, -200 ], "parameters": { "color": 3, "width": 620, "height": 420, "content": "## Vector Centroid API\nGET the configured webhook URL with vectors as a URL-encoded JSON array of equal-length finite numeric arrays. Responds with centroid or error as JSON, HTTP 200. See README for an example request." }, "typeVersion": 1 }, { "id": "e4793b20-bfa6-4b08-b46c-f92d1c9c2622", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ 640, -280 ], "parameters": { "color": 4, "width": 700, "height": 500, "content": "## Vector Centroid API\nGET the configured webhook URL with vectors as a URL-encoded JSON array of equal-length finite numeric arrays. Responds with centroid or error as JSON, HTTP 200. See README for an example request." }, "typeVersion": 1 }, { "id": "e0ac1c4d-0435-44d1-ba87-0cfc9dea207b", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ 1340, -200 ], "parameters": { "color": 2, "width": 680, "height": 420, "content": "## Vector Centroid API\nGET the configured webhook URL with vectors as a URL-encoded JSON array of equal-length finite numeric arrays. Responds with centroid or error as JSON, HTTP 200. See README for an example request." }, "typeVersion": 1 }, { "id": "2b4fbae7-c2e5-4666-ba9f-72a5313fc16f", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [ -820, -200 ], "parameters": { "color": 4, "width": 840, "height": 420, "content": "## Vector Centroid API\nGET the configured webhook URL with vectors as a URL-encoded JSON array of equal-length finite numeric arrays. Responds with centroid or error as JSON, HTTP 200. See README for an example request." }, "typeVersion": 1 } ], "active": false, "pinData": {}, "settings": { "executionOrder": "v1" }, "connections": { "Receive Vectors": { "main": [ [ { "node": "Extract & Parse Vectors", "type": "main", "index": 0 } ] ] }, "Extract & Parse Vectors": { "main": [ [ { "node": "Validate & Compute Centroid", "type": "main", "index": 0 } ] ] }, "Validate & Compute Centroid": { "main": [ [ { "node": "Return Centroid Response", "type": "main", "index": 0 } ] ] } } }