641 lines
16 KiB
JSON
641 lines
16 KiB
JSON
{
|
|||
|
|
"name": "78 FAQ import + LLM calls (answer)",
|
||
|
|
"nodes": [
|
||
|
|
{
|
||
|
|
"name": "Import webhook",
|
||
|
|
"type": "n8n-nodes-base.webhook",
|
||
|
|
"typeVersion": 2,
|
||
|
|
"parameters": {
|
||
|
|
"httpMethod": "POST",
|
||
|
|
"path": "my-faq-import",
|
||
|
|
"responseMode": "responseNode",
|
||
|
|
"options": {}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
0,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "97923cda-6ae1-50d4-a0ad-df64c161c39c",
|
||
|
|
"webhookId": "23a35671-e3aa-5f09-a094-45b3da4c643c"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Run check",
|
||
|
|
"type": "n8n-nodes-base.httpRequest",
|
||
|
|
"typeVersion": 4.2,
|
||
|
|
"parameters": {
|
||
|
|
"url": "http://localhost:5678/webhook/my-faq-check",
|
||
|
|
"options": {
|
||
|
|
"response": {
|
||
|
|
"response": {
|
||
|
|
"neverError": true
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"timeout": 30000
|
||
|
|
},
|
||
|
|
"method": "POST",
|
||
|
|
"sendBody": true,
|
||
|
|
"specifyBody": "json",
|
||
|
|
"jsonBody": "={{ JSON.stringify($json.body) }}"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
220,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "9ebb8863-ee15-58d6-9115-b6ff5a1bbfd0"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Checked?",
|
||
|
|
"type": "n8n-nodes-base.if",
|
||
|
|
"typeVersion": 2.2,
|
||
|
|
"parameters": {
|
||
|
|
"conditions": {
|
||
|
|
"options": {
|
||
|
|
"caseSensitive": true,
|
||
|
|
"leftValue": "",
|
||
|
|
"typeValidation": "loose",
|
||
|
|
"version": 2
|
||
|
|
},
|
||
|
|
"conditions": [
|
||
|
|
{
|
||
|
|
"id": "c1",
|
||
|
|
"leftValue": "={{ Array.isArray($json.rows) && $json.rows.length > 0 }}",
|
||
|
|
"rightValue": "",
|
||
|
|
"operator": {
|
||
|
|
"type": "boolean",
|
||
|
|
"operation": "true",
|
||
|
|
"singleValue": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"combinator": "and"
|
||
|
|
},
|
||
|
|
"options": {}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
440,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "4a3efc44-a09f-5cf8-8654-8c976fc86008"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Reject body",
|
||
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
||
|
|
"typeVersion": 1.1,
|
||
|
|
"parameters": {
|
||
|
|
"respondWith": "json",
|
||
|
|
"responseBody": "={{ JSON.stringify({ error: $json.error ?? 'check failed' }) }}",
|
||
|
|
"options": {
|
||
|
|
"responseCode": 400
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
660,
|
||
|
|
760
|
||
|
|
],
|
||
|
|
"id": "88c8455e-da32-5781-8c2d-40c1262fcd70"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Batch ok?",
|
||
|
|
"type": "n8n-nodes-base.if",
|
||
|
|
"typeVersion": 2.2,
|
||
|
|
"parameters": {
|
||
|
|
"conditions": {
|
||
|
|
"options": {
|
||
|
|
"caseSensitive": true,
|
||
|
|
"leftValue": "",
|
||
|
|
"typeValidation": "loose",
|
||
|
|
"version": 2
|
||
|
|
},
|
||
|
|
"conditions": [
|
||
|
|
{
|
||
|
|
"id": "c1",
|
||
|
|
"leftValue": "={{ $json.invalid / $json.total <= ($('Import webhook').first().json.body.max_invalid_ratio ?? 0.3) }}",
|
||
|
|
"rightValue": "",
|
||
|
|
"operator": {
|
||
|
|
"type": "boolean",
|
||
|
|
"operation": "true",
|
||
|
|
"singleValue": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"combinator": "and"
|
||
|
|
},
|
||
|
|
"options": {}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
660,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "74cca906-ea01-5106-a9b7-e9166ccfa367"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Reject batch",
|
||
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
||
|
|
"typeVersion": 1.1,
|
||
|
|
"parameters": {
|
||
|
|
"respondWith": "json",
|
||
|
|
"responseBody": "={{ JSON.stringify({ error: 'batch rejected', batch: $('Run check').first().json.batch, invalid_ratio: Math.round($('Run check').first().json.invalid / $('Run check').first().json.total * 10000) / 10000, max_invalid_ratio: ($('Import webhook').first().json.body.max_invalid_ratio ?? 0.3), codes: $('Run check').first().json.codes, llm_calls: 0 }) }}",
|
||
|
|
"options": {
|
||
|
|
"responseCode": 422
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
1320,
|
||
|
|
560
|
||
|
|
],
|
||
|
|
"id": "50f5afd9-e4fb-5f03-b99c-b0bbbd02f637"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Log rejected",
|
||
|
|
"type": "n8n-nodes-base.httpRequest",
|
||
|
|
"typeVersion": 4.2,
|
||
|
|
"parameters": {
|
||
|
|
"url": "http://data-api:8800/quality-log",
|
||
|
|
"options": {
|
||
|
|
"response": {
|
||
|
|
"response": {
|
||
|
|
"neverError": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"method": "POST",
|
||
|
|
"sendBody": true,
|
||
|
|
"specifyBody": "json",
|
||
|
|
"jsonBody": "={{ JSON.stringify({ batch: $json.batch, dataset: 'faq', total: $json.total, valid: $json.valid, quarantined: 0, rejected: true, score: 0, codes: $json.codes }) }}"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
880,
|
||
|
|
560
|
||
|
|
],
|
||
|
|
"id": "b1d03d7a-d131-59b4-b7c3-63c90c4bd3e2"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Alert rejected",
|
||
|
|
"type": "n8n-nodes-base.httpRequest",
|
||
|
|
"typeVersion": 4.2,
|
||
|
|
"parameters": {
|
||
|
|
"url": "http://data-api:8800/alerts",
|
||
|
|
"options": {
|
||
|
|
"response": {
|
||
|
|
"response": {
|
||
|
|
"neverError": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"method": "POST",
|
||
|
|
"sendBody": true,
|
||
|
|
"specifyBody": "json",
|
||
|
|
"jsonBody": "={{ JSON.stringify({ workflow: 'faq-import', node: 'Batch ok?', severity: 'high', reason: 'batch_rejected', batch: $('Run check').first().json.batch, message: $('Run check').first().json.batch + ' rejected' }) }}"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
1100,
|
||
|
|
560
|
||
|
|
],
|
||
|
|
"id": "0f3fae58-f846-5ff3-99b0-ad519ff51546"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Split rows",
|
||
|
|
"type": "n8n-nodes-base.code",
|
||
|
|
"typeVersion": 2,
|
||
|
|
"parameters": {
|
||
|
|
"jsCode": "const c = $('Run check').first().json;\nconst items = $('Import webhook').first().json.body.items;\nreturn c.rows.map((r, i) => ({ json: { ...r, row: items[i], batch: c.batch } }));"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
880,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "aa264c2a-0b2c-5c68-ab00-48e193d952d8"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Only passed",
|
||
|
|
"type": "n8n-nodes-base.code",
|
||
|
|
"typeVersion": 2,
|
||
|
|
"parameters": {
|
||
|
|
"jsCode": "return $input.all().filter((i) => i.json.ok);"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
1100,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "57ba3d3a-7a75-5848-90f7-cc4072007dd2"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Judge",
|
||
|
|
"type": "@n8n/n8n-nodes-langchain.agent",
|
||
|
|
"typeVersion": 3.1,
|
||
|
|
"parameters": {
|
||
|
|
"promptType": "define",
|
||
|
|
"text": "=제목: {{ $json.row.title }}\n답: {{ $json.row.answer }}",
|
||
|
|
"options": {
|
||
|
|
"systemMessage": "You check a company IT FAQ entry before it is published. Does the answer actually answer the title's topic? Ignore style. Return only JSON, no code fence: {\"match\": true, \"reason\": \"short reason in Korean\"}",
|
||
|
|
"maxIterations": 1
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"onError": "continueRegularOutput",
|
||
|
|
"position": [
|
||
|
|
1320,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "8936b8b1-19a9-57fe-aae5-d934a6c1e6c7"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Judge model",
|
||
|
|
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
|
||
|
|
"typeVersion": 1.2,
|
||
|
|
"parameters": {
|
||
|
|
"model": {
|
||
|
|
"__rl": true,
|
||
|
|
"mode": "id",
|
||
|
|
"value": "gpt-4.1-mini"
|
||
|
|
},
|
||
|
|
"options": {
|
||
|
|
"temperature": 0
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"credentials": {
|
||
|
|
"openAiApi": {
|
||
|
|
"id": "openAiCourse0001",
|
||
|
|
"name": "OpenAI (.env)"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
1320,
|
||
|
|
520
|
||
|
|
],
|
||
|
|
"id": "ada85f33-792e-562b-8802-463ced397599"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Decide",
|
||
|
|
"type": "n8n-nodes-base.code",
|
||
|
|
"typeVersion": 2,
|
||
|
|
"parameters": {
|
||
|
|
"jsCode": "const judged = $('Only passed').all().map((item, i) => {\n let v = { match: false, reason: 'judge unreadable' };\n try { v = JSON.parse(String($('Judge').all()[i].json.output ?? '').replace(/^```(json)?\\s*|```$/g, '')); } catch (e) {}\n return { ...item.json, ok: v.match === true, errors: v.match === true ? [] : ['llm_mismatch'], reason: String(v.reason ?? '') };\n});\nlet k = 0;\nreturn $('Split rows').all().map((i) => ({ json: i.json.ok ? judged[k++] : i.json }));"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
1540,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "43e33f20-a354-548d-98fe-a22a8a295de5"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Store row",
|
||
|
|
"type": "n8n-nodes-base.httpRequest",
|
||
|
|
"typeVersion": 4.2,
|
||
|
|
"parameters": {
|
||
|
|
"url": "={{ $json.ok ? 'http://data-api:8800/faq/add' : 'http://data-api:8800/quarantine' }}",
|
||
|
|
"options": {
|
||
|
|
"response": {
|
||
|
|
"response": {
|
||
|
|
"neverError": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"method": "POST",
|
||
|
|
"sendBody": true,
|
||
|
|
"specifyBody": "json",
|
||
|
|
"jsonBody": "={{ JSON.stringify($json.ok ? $json.row : { items: [{ batch: $json.batch, row: $json.row, errors: $json.errors }] }) }}"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
1760,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "8df856a9-afff-5685-8095-51fceddbd4de"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Summarize",
|
||
|
|
"type": "n8n-nodes-base.code",
|
||
|
|
"typeVersion": 2,
|
||
|
|
"parameters": {
|
||
|
|
"jsCode": "const c = $('Run check').first().json;\nconst rows = $('Decide').all().map((i) => i.json);\nconst imported = rows.filter((r) => r.ok);\nconst quarantined = rows.filter((r) => !r.ok);\nconst codes = { ...c.codes };\nfor (const r of quarantined) for (const e of r.errors) if (e === 'llm_mismatch') codes[e] = (codes[e] ?? 0) + 1;\nreturn [{ json: { batch: c.batch, total: c.total, imported: imported.length, quarantined: quarantined.length, rejected: false,\n score: Math.round(imported.length / c.total * 10000) / 10000, max_invalid_ratio: ($('Import webhook').first().json.body.max_invalid_ratio ?? 0.3),\n codes, imported_ids: imported.map((r) => r.id), quarantined_ids: quarantined.map((r) => r.id), llm_calls: $('Only passed').all().length } }];"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
1980,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "c287c65f-99fd-59ef-a44d-dc4b021d7a9c"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Log quality",
|
||
|
|
"type": "n8n-nodes-base.httpRequest",
|
||
|
|
"typeVersion": 4.2,
|
||
|
|
"parameters": {
|
||
|
|
"url": "http://data-api:8800/quality-log",
|
||
|
|
"options": {
|
||
|
|
"response": {
|
||
|
|
"response": {
|
||
|
|
"neverError": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"method": "POST",
|
||
|
|
"sendBody": true,
|
||
|
|
"specifyBody": "json",
|
||
|
|
"jsonBody": "={{ JSON.stringify({ batch: $('Summarize').first().json.batch, dataset: 'faq', total: $('Summarize').first().json.total, valid: $('Summarize').first().json.imported, quarantined: $('Summarize').first().json.quarantined, rejected: false, score: $('Summarize').first().json.score, codes: $('Summarize').first().json.codes }) }}"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
2200,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "9607be48-7b62-5f67-9aec-23db3fb0fbb8"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Low score?",
|
||
|
|
"type": "n8n-nodes-base.if",
|
||
|
|
"typeVersion": 2.2,
|
||
|
|
"parameters": {
|
||
|
|
"conditions": {
|
||
|
|
"options": {
|
||
|
|
"caseSensitive": true,
|
||
|
|
"leftValue": "",
|
||
|
|
"typeValidation": "loose",
|
||
|
|
"version": 2
|
||
|
|
},
|
||
|
|
"conditions": [
|
||
|
|
{
|
||
|
|
"id": "c1",
|
||
|
|
"leftValue": "={{ $('Summarize').first().json.score < 0.9 }}",
|
||
|
|
"rightValue": "",
|
||
|
|
"operator": {
|
||
|
|
"type": "boolean",
|
||
|
|
"operation": "true",
|
||
|
|
"singleValue": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"combinator": "and"
|
||
|
|
},
|
||
|
|
"options": {}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
2420,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "4d32f16f-6554-580b-83eb-2c489df417d3"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Alert low score",
|
||
|
|
"type": "n8n-nodes-base.httpRequest",
|
||
|
|
"typeVersion": 4.2,
|
||
|
|
"parameters": {
|
||
|
|
"url": "http://data-api:8800/alerts",
|
||
|
|
"options": {
|
||
|
|
"response": {
|
||
|
|
"response": {
|
||
|
|
"neverError": true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"method": "POST",
|
||
|
|
"sendBody": true,
|
||
|
|
"specifyBody": "json",
|
||
|
|
"jsonBody": "={{ JSON.stringify({ workflow: 'faq-import', node: 'Low score?', severity: 'high', reason: 'low_quality', batch: $('Summarize').first().json.batch, score: $('Summarize').first().json.score, message: $('Summarize').first().json.batch + ' quality ' + $('Summarize').first().json.score }) }}"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
2640,
|
||
|
|
160
|
||
|
|
],
|
||
|
|
"id": "e7dcfdb3-8ed7-5783-93cb-4daf2a75cbb6"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Result again",
|
||
|
|
"type": "n8n-nodes-base.code",
|
||
|
|
"typeVersion": 2,
|
||
|
|
"parameters": {
|
||
|
|
"jsCode": "return [{ json: $('Summarize').first().json }];"
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
2860,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "90b42f0a-eaa4-55d7-b579-c2e6c67ea701"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Send result",
|
||
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
||
|
|
"typeVersion": 1.1,
|
||
|
|
"parameters": {
|
||
|
|
"respondWith": "json",
|
||
|
|
"responseBody": "={{ $json }}",
|
||
|
|
"options": {}
|
||
|
|
},
|
||
|
|
"position": [
|
||
|
|
3080,
|
||
|
|
300
|
||
|
|
],
|
||
|
|
"id": "700d4355-509a-546a-936e-d8e96c297925"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"connections": {
|
||
|
|
"Import webhook": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Run check",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Run check": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Checked?",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Checked?": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Batch ok?",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
],
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Reject body",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Batch ok?": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Split rows",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
],
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Log rejected",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Log rejected": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Alert rejected",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Alert rejected": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Reject batch",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Split rows": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Only passed",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Only passed": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Judge",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Judge": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Decide",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Judge model": {
|
||
|
|
"ai_languageModel": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Judge",
|
||
|
|
"type": "ai_languageModel",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Decide": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Store row",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Store row": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Summarize",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Summarize": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Log quality",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Log quality": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Low score?",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Low score?": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Alert low score",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
],
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Result again",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Alert low score": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Result again",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
},
|
||
|
|
"Result again": {
|
||
|
|
"main": [
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"node": "Send result",
|
||
|
|
"type": "main",
|
||
|
|
"index": 0
|
||
|
|
}
|
||
|
|
]
|
||
|
|
]
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"settings": {
|
||
|
|
"executionOrder": "v1"
|
||
|
|
}
|
||
|
|
}
|