From c67561e04700a39d0f222bfb5bc169011af4fad8 Mon Sep 17 00:00:00 2001 From: ph34444 Date: Mon, 16 Mar 2026 17:21:33 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20workflow=20C=20=E2=80=93=20knowledge=20?= =?UTF-8?q?base=20auto-update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- n8n-workflows/workflow-c-kb-update.json | 988 ++++++++++++++++++++++++ 1 file changed, 988 insertions(+) create mode 100644 n8n-workflows/workflow-c-kb-update.json diff --git a/n8n-workflows/workflow-c-kb-update.json b/n8n-workflows/workflow-c-kb-update.json new file mode 100644 index 0000000..6e8bb30 --- /dev/null +++ b/n8n-workflows/workflow-c-kb-update.json @@ -0,0 +1,988 @@ +{ + "name": "Workflow C – Knowledge Base Auto-Update", + "description": "Triggered by Workflow B when solution is executed. Generates embeddings, inserts new KB entries, updates existing entry frequencies, and logs all operations.", + "nodes": [ + { + "id": "uuid-webhook-trigger-c-1", + "name": "Webhook Trigger", + "type": "n8n-nodes-base.webhook", + "typeVersion": 1, + "position": [ + 250, + 200 + ], + "parameters": { + "path": "workflow-c", + "httpMethod": "POST", + "options": {} + }, + "webhookId": "workflow-c-webhook-id" + }, + { + "id": "uuid-validate-payload-c-1", + "name": "Validate Payload", + "type": "n8n-nodes-base.if", + "typeVersion": 1, + "position": [ + 450, + 200 + ], + "parameters": { + "conditions": { + "number": [ + { + "comparator": "exists", + "value1": "={{ $json.ticket_id }}", + "value2": "" + }, + { + "comparator": "exists", + "value1": "={{ $json.ai_suggestion }}", + "value2": "" + } + ] + }, + "combineOperation": "AND" + } + }, + { + "id": "uuid-parse-suggestion-c-1", + "name": "Parse AI Suggestion", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 650, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "ticket_id", + "value": "={{ $json.ticket_id }}", + "type": "string" + }, + { + "name": "conversation_id", + "value": "={{ $json.conversation_id }}", + "type": "string" + }, + { + "name": "ai_suggestion_parsed", + "value": "={{ typeof $json.ai_suggestion === 'string' ? JSON.parse($json.ai_suggestion) : $json.ai_suggestion }}", + "type": "object" + }, + { + "name": "execution_type", + "value": "={{ $json.execution_type }}", + "type": "string" + }, + { + "name": "timestamp", + "value": "={{ $json.timestamp || new Date().toISOString() }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-extract-kb-fields-c-1", + "name": "Extract KB Fields", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 850, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "problem_text", + "value": "={{ $json.ai_suggestion_parsed.problem_text || $json.ai_suggestion_parsed.problem || $json.subject || 'Unknown problem' }}", + "type": "string" + }, + { + "name": "kategorie", + "value": "={{ $json.ai_suggestion_parsed.kategorie || $json.ai_suggestion_parsed.category || 'Uncategorized' }}", + "type": "string" + }, + { + "name": "lösung", + "value": "={{ $json.ai_suggestion_parsed.lösung || $json.ai_suggestion_parsed.solution || 'No solution provided' }}", + "type": "string" + }, + { + "name": "embedding_input", + "value": "={{ $json.kategorie + ' | ' + $json.problem_text }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-litellm-embedding-c-1", + "name": "LiteLLM Generate Embedding", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1050, + 200 + ], + "parameters": { + "authentication": "none", + "url": "={{ $env.LITELLM_API_URL || 'http://litellm:4000' }}/v1/embeddings", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"model\": \"text-embedding-3-small\",\n \"input\": $json.embedding_input\n} }}" + } + }, + { + "id": "uuid-extract-embedding-c-1", + "name": "Extract Embedding Vector", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1250, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "embedding_vector", + "value": "={{ $json.data[0].embedding }}", + "type": "object" + }, + { + "name": "embedding_dim", + "value": "={{ $json.data[0].embedding.length }}", + "type": "number" + } + ] + } + } + }, + { + "id": "uuid-milvus-insert-c-1", + "name": "Milvus Insert New KB Entry", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1450, + 200 + ], + "parameters": { + "authentication": "none", + "url": "={{ $env.MILVUS_API_URL || 'http://milvus:19530' }}/v1/vector_db/knowledge_base/insert", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"entries\": [\n {\n \"id\": \"kb_\" + $json.ticket_id + \"_\" + Date.now(),\n \"problem_text\": $json.problem_text,\n \"kategorie\": $json.kategorie,\n \"lösung\": $json.lösung,\n \"häufigkeit\": 1,\n \"embedding\": $json.embedding_vector,\n \"timestamp\": new Date().toISOString(),\n \"ticket_id\": $json.ticket_id,\n \"conversation_id\": $json.conversation_id,\n \"source\": \"workflow-c\",\n \"status\": \"ACTIVE\"\n }\n ]\n} }}" + } + }, + { + "id": "uuid-extract-insert-result-c-1", + "name": "Extract Insert Result", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1650, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "kb_entry_id", + "value": "={{ $json.ids ? $json.ids[0] : 'kb_' + $json.ticket_id + '_' + Date.now() }}", + "type": "string" + }, + { + "name": "insert_status", + "value": "={{ $json.status || 'SUCCESS' }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-milvus-query-similar-c-1", + "name": "Milvus Query Similar Entries", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1850, + 200 + ], + "parameters": { + "authentication": "none", + "url": "={{ $env.MILVUS_API_URL || 'http://milvus:19530' }}/v1/vector_db/knowledge_base/search", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"vector\": $json.embedding_vector,\n \"limit\": 5,\n \"params\": {\n \"nprobe\": 10\n },\n \"expr\": \"status == 'ACTIVE' AND kategorie == '\" + $json.kategorie + \"'\"\n} }}", + "options": { + "otherOptions": { + "allowUnauthorizedCerts": true + } + } + } + }, + { + "id": "uuid-filter-similar-high-score-c-1", + "name": "Filter Similar > 0.85", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 2050, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "similar_entries", + "value": "={{ ($json.results || []).filter(r => r.distance >= 0.85) }}", + "type": "object" + } + ] + } + } + }, + { + "id": "uuid-check-similar-entries-c-1", + "name": "Check If Similar Exist", + "type": "n8n-nodes-base.if", + "typeVersion": 1, + "position": [ + 2250, + 200 + ], + "parameters": { + "conditions": { + "number": [ + { + "comparator": "gt", + "value1": "={{ $json.similar_entries.length }}", + "value2": "0" + } + ] + } + } + }, + { + "id": "uuid-milvus-update-frequency-c-1", + "name": "Milvus Update Frequency", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 2450, + 100 + ], + "parameters": { + "authentication": "none", + "url": "={{ $env.MILVUS_API_URL || 'http://milvus:19530' }}/v1/vector_db/knowledge_base/update", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"updates\": $json.similar_entries.map(entry => ({\n \"id\": entry.id,\n \"häufigkeit\": (entry.häufigkeit || 1) + 1,\n \"last_updated\": new Date().toISOString()\n }))\n} }}" + } + }, + { + "id": "uuid-extract-frequency-update-c-1", + "name": "Extract Frequency Update Result", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 2650, + 100 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "frequency_update_count", + "value": "={{ $json.modified_count || $json.similar_entries.length || 0 }}", + "type": "number" + } + ] + } + } + }, + { + "id": "uuid-postgres-insert-audit-c-1", + "name": "PostgreSQL Insert Audit Log", + "type": "n8n-nodes-base.postgres", + "typeVersion": 2, + "position": [ + 2850, + 200 + ], + "parameters": { + "operation": "insert", + "schema": "public", + "table": "knowledge_base_updates", + "columns": { + "columns": [ + { + "column": "ticket_id", + "type": "string", + "value": "={{ $json.ticket_id }}" + }, + { + "column": "conversation_id", + "type": "string", + "value": "={{ $json.conversation_id }}" + }, + { + "column": "problem_text", + "type": "string", + "value": "={{ $json.problem_text }}" + }, + { + "column": "kategorie", + "type": "string", + "value": "={{ $json.kategorie }}" + }, + { + "column": "lösung", + "type": "string", + "value": "={{ $json.lösung }}" + }, + { + "column": "kb_entry_id", + "type": "string", + "value": "={{ $json.kb_entry_id }}" + }, + { + "column": "embedding_dim", + "type": "number", + "value": "={{ $json.embedding_dim }}" + }, + { + "column": "frequency_updates_count", + "type": "number", + "value": "={{ $json.frequency_update_count || 0 }}" + }, + { + "column": "status", + "type": "string", + "value": "EXECUTED" + }, + { + "column": "source", + "type": "string", + "value": "workflow-c" + }, + { + "column": "created_at", + "type": "string", + "value": "={{ new Date().toISOString() }}" + }, + { + "column": "updated_at", + "type": "string", + "value": "={{ new Date().toISOString() }}" + } + ] + } + }, + "credentials": { + "postgres": "PostgreSQL Connection" + } + }, + { + "id": "uuid-success-response-c-1", + "name": "Success Response", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 3050, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "success", + "value": true, + "type": "boolean" + }, + { + "name": "message", + "value": "Knowledge base entry created and frequencies updated successfully", + "type": "string" + }, + { + "name": "kb_entry_id", + "value": "={{ $json.kb_entry_id }}", + "type": "string" + }, + { + "name": "similar_entries_updated", + "value": "={{ $json.frequency_update_count || 0 }}", + "type": "number" + }, + { + "name": "timestamp", + "value": "={{ new Date().toISOString() }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-skip-frequency-update-c-1", + "name": "Skip Frequency Update", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 2450, + 350 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "frequency_update_count", + "value": "0", + "type": "number" + } + ] + } + } + }, + { + "id": "uuid-merge-frequency-result-c-1", + "name": "Merge Frequency Result", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 2650, + 250 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "frequency_update_count", + "value": "={{ $json.frequency_update_count || 0 }}", + "type": "number" + } + ] + } + } + }, + { + "id": "uuid-error-log-embedding-c-1", + "name": "Error: Embedding Generation Failed", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1050, + 500 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "error_type", + "value": "EMBEDDING_GENERATION_FAILED", + "type": "string" + }, + { + "name": "error_message", + "value": "={{ $error.message }}", + "type": "string" + }, + { + "name": "ticket_id", + "value": "={{ $json.ticket_id }}", + "type": "string" + }, + { + "name": "timestamp", + "value": "={{ new Date().toISOString() }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-error-log-milvus-c-1", + "name": "Error: Milvus Insert Failed", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1450, + 500 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "error_type", + "value": "MILVUS_INSERT_FAILED", + "type": "string" + }, + { + "name": "error_message", + "value": "={{ $error.message }}", + "type": "string" + }, + { + "name": "ticket_id", + "value": "={{ $json.ticket_id }}", + "type": "string" + }, + { + "name": "timestamp", + "value": "={{ new Date().toISOString() }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-error-log-postgres-c-1", + "name": "Error: PostgreSQL Audit Log Failed", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 2850, + 500 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "error_type", + "value": "POSTGRES_AUDIT_FAILED", + "type": "string" + }, + { + "name": "error_message", + "value": "={{ $error.message }}", + "type": "string" + }, + { + "name": "ticket_id", + "value": "={{ $json.ticket_id }}", + "type": "string" + }, + { + "name": "timestamp", + "value": "={{ new Date().toISOString() }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-postgres-error-handler-c-1", + "name": "PostgreSQL Insert Error Handler", + "type": "n8n-nodes-base.postgres", + "typeVersion": 2, + "position": [ + 3050, + 500 + ], + "parameters": { + "operation": "insert", + "schema": "public", + "table": "knowledge_base_errors", + "columns": { + "columns": [ + { + "column": "ticket_id", + "type": "string", + "value": "={{ $json.ticket_id }}" + }, + { + "column": "error_type", + "type": "string", + "value": "={{ $json.error_type }}" + }, + { + "column": "error_message", + "type": "string", + "value": "={{ $json.error_message }}" + }, + { + "column": "workflow", + "type": "string", + "value": "workflow-c" + }, + { + "column": "created_at", + "type": "string", + "value": "={{ new Date().toISOString() }}" + } + ] + } + }, + "credentials": { + "postgres": "PostgreSQL Connection" + } + }, + { + "id": "uuid-error-response-c-1", + "name": "Error Response", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 3250, + 500 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "success", + "value": false, + "type": "boolean" + }, + { + "name": "error_type", + "value": "={{ $json.error_type }}", + "type": "string" + }, + { + "name": "error_message", + "value": "={{ $json.error_message }}", + "type": "string" + }, + { + "name": "ticket_id", + "value": "={{ $json.ticket_id }}", + "type": "string" + }, + { + "name": "timestamp", + "value": "={{ new Date().toISOString() }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-validation-failed-c-1", + "name": "Validation Failed", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 450, + 500 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "success", + "value": false, + "type": "boolean" + }, + { + "name": "error_type", + "value": "VALIDATION_FAILED", + "type": "string" + }, + { + "name": "error_message", + "value": "Missing required fields: ticket_id or ai_suggestion", + "type": "string" + }, + { + "name": "timestamp", + "value": "={{ new Date().toISOString() }}", + "type": "string" + } + ] + } + } + } + ], + "connections": { + "Webhook Trigger": { + "main": [ + [ + { + "node": "Validate Payload", + "index": 0 + } + ] + ] + }, + "Validate Payload": { + "main": [ + [ + { + "node": "Parse AI Suggestion", + "index": 0 + } + ], + [ + { + "node": "Validation Failed", + "index": 0 + } + ] + ] + }, + "Parse AI Suggestion": { + "main": [ + [ + { + "node": "Extract KB Fields", + "index": 0 + } + ] + ] + }, + "Extract KB Fields": { + "main": [ + [ + { + "node": "LiteLLM Generate Embedding", + "index": 0 + } + ] + ] + }, + "LiteLLM Generate Embedding": { + "main": [ + [ + { + "node": "Extract Embedding Vector", + "index": 0 + } + ], + [ + { + "node": "Error: Embedding Generation Failed", + "index": 0 + } + ] + ] + }, + "Extract Embedding Vector": { + "main": [ + [ + { + "node": "Milvus Insert New KB Entry", + "index": 0 + } + ] + ] + }, + "Milvus Insert New KB Entry": { + "main": [ + [ + { + "node": "Extract Insert Result", + "index": 0 + } + ], + [ + { + "node": "Error: Milvus Insert Failed", + "index": 0 + } + ] + ] + }, + "Extract Insert Result": { + "main": [ + [ + { + "node": "Milvus Query Similar Entries", + "index": 0 + } + ] + ] + }, + "Milvus Query Similar Entries": { + "main": [ + [ + { + "node": "Filter Similar > 0.85", + "index": 0 + } + ] + ] + }, + "Filter Similar > 0.85": { + "main": [ + [ + { + "node": "Check If Similar Exist", + "index": 0 + } + ] + ] + }, + "Check If Similar Exist": { + "main": [ + [ + { + "node": "Milvus Update Frequency", + "index": 0 + } + ], + [ + { + "node": "Skip Frequency Update", + "index": 0 + } + ] + ] + }, + "Milvus Update Frequency": { + "main": [ + [ + { + "node": "Extract Frequency Update Result", + "index": 0 + } + ] + ] + }, + "Extract Frequency Update Result": { + "main": [ + [ + { + "node": "Merge Frequency Result", + "index": 0 + } + ] + ] + }, + "Skip Frequency Update": { + "main": [ + [ + { + "node": "Merge Frequency Result", + "index": 0 + } + ] + ] + }, + "Merge Frequency Result": { + "main": [ + [ + { + "node": "PostgreSQL Insert Audit Log", + "index": 0 + } + ] + ] + }, + "PostgreSQL Insert Audit Log": { + "main": [ + [ + { + "node": "Success Response", + "index": 0 + } + ], + [ + { + "node": "Error: PostgreSQL Audit Log Failed", + "index": 0 + } + ] + ] + }, + "Success Response": { + "main": [ + [] + ] + }, + "Error: Embedding Generation Failed": { + "main": [ + [ + { + "node": "PostgreSQL Insert Error Handler", + "index": 0 + } + ] + ] + }, + "Error: Milvus Insert Failed": { + "main": [ + [ + { + "node": "PostgreSQL Insert Error Handler", + "index": 0 + } + ] + ] + }, + "Error: PostgreSQL Audit Log Failed": { + "main": [ + [ + { + "node": "PostgreSQL Insert Error Handler", + "index": 0 + } + ] + ] + }, + "PostgreSQL Insert Error Handler": { + "main": [ + [ + { + "node": "Error Response", + "index": 0 + } + ] + ] + }, + "Error Response": { + "main": [ + [] + ] + }, + "Validation Failed": { + "main": [ + [] + ] + } + } +}