{
  "name": "24h AI Recovery",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 23
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        -192,
        0
      ],
      "id": "867641de-109f-429b-be79-4ebe98e20c9a",
      "name": "Schedule Trigger (24h)"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        688,
        0
      ],
      "id": "9351104d-62a2-44b6-b947-5e56142be633",
      "name": "Loop Over Articles"
    },
    {
      "parameters": {
        "jsCode": "const item = $input.first();\nconst textForLLM = `${item.json.title}\\n\\n${item.json.content || item.json.content_clean || ''}`;\n\nconst systemPrompt = 'You are a news analyst. Analyze the article and determine:\\n1. Whether it relates to Arctic topics\\n2. If yes, to which category\\n3. Create a brief summary\\nRespond ONLY in JSON format without additional text.';\n\nconst userPrompt = [\n  'You are an AI assistant analyzing news articles for an Arctic news aggregation system.',\n  '',\n  'TASK: Analyze the article and return a JSON object with exactly these three fields:',\n  '{',\n  '  \"is_arctic\": boolean,',\n  '  \"arctic_topic\": string,',\n  '  \"summary_ai\": string',\n  '}',\n  '',\n  'FIELD DEFINITIONS:',\n  '',\n  '1. is_arctic (boolean): true if Arctic-related, false otherwise.',\n  '   Consider Arctic-related if it mentions: Arctic region/countries/territories,',\n  '   Arctic shipping/Northern Sea Route, Arctic climate/environment/wildlife,',\n  '   Arctic resources (oil/gas/minerals), Arctic indigenous peoples,',\n  '   Arctic research/expeditions, Arctic geopolitics/military, Arctic infrastructure.',\n  '',\n  '2. arctic_topic (string):',\n  '   - If is_arctic is false: \"\u041d\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0410\u0440\u043a\u0442\u0438\u043a\u0435\"',\n  '   - If is_arctic is true, pick ONE from:',\n  '     \"\u0410\u0440\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u0443\u0434\u043e\u0445\u043e\u0434\u0441\u0442\u0432\u043e\", \"\u041a\u043b\u0438\u043c\u0430\u0442 \u0438 \u044d\u043a\u043e\u043b\u043e\u0433\u0438\u044f\", \"\u042d\u043d\u0435\u0440\u0433\u0435\u0442\u0438\u043a\u0430 \u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u044b\",',\n  '     \"\u0413\u0435\u043e\u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\", \"\u041a\u043e\u0440\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0440\u043e\u0434\u044b\", \"\u041d\u0430\u0443\u043a\u0430 \u0438 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\",',\n  '     \"\u0418\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435\"',\n  '',\n  '3. summary_ai (string): 2-3 sentence summary in Russian.',\n  '',\n  'ARTICLE:',\n  textForLLM,\n  '',\n  'Return ONLY valid JSON, no additional text or markdown.'\n].join('\\n');\n\nconst requestBody = {\n  model: 'nvidia/nemotron-3-super-120b-a12b:free',\n  messages: [\n    { role: 'system', content: systemPrompt },\n    { role: 'user', content: userPrompt }\n  ],\n  response_format: { type: 'json_object' },\n  temperature: 0.3,\n  max_tokens: 1500\n};\n\nitem.json.llm_request_body = JSON.stringify(requestBody);\nitem.json.article_id = item.json.id;\n\nreturn [item];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        928,
        0
      ],
      "id": "0762a98f-d709-4210-9ddd-031c11c4a613",
      "name": "Build Request Body"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://openrouter.ai/api/v1/chat/completions",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer \u0412\u0430\u0448_\u043a\u043b\u044e\u0447"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ $json.llm_request_body }}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        1168,
        0
      ],
      "id": "bce49a5f-335f-4cde-a3cd-31da6094f63b",
      "name": "AnalysAI"
    },
    {
      "parameters": {
        "jsCode": "const response = $input.first().json;\nconst articleId = $('Build Request Body').first().json.article_id;\n\nconst contentRaw = response.choices?.[0]?.message?.content;\n\nif (!contentRaw) {\n  throw new Error('\u041d\u0435\u0442 content \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 LLM');\n}\n\nconst parsed = JSON.parse(contentRaw.trim());\n\nconst endTime = new Date();\n\nreturn [{\n  json: {\n    article_id: articleId,\n    is_arctic: parsed.is_arctic,\n    arctic_topic: parsed.arctic_topic,\n    summary_ai: parsed.summary_ai,\n    tokens_used: response.usage?.total_tokens,\n    processed_at: endTime.toISOString()\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1408,
        0
      ],
      "id": "491197fd-877e-4baa-9963-43c7503943e3",
      "name": "Parse LLM Response"
    },
    {
      "parameters": {
        "operation": "update",
        "collection": "news",
        "itemId": "={{ $json.article_id }}",
        "collectionFields": {
          "fields": {
            "field": [
              {
                "name": "summary_ai",
                "value": "={{ $json.summary_ai }}"
              },
              {
                "name": "is_arctic",
                "value": "={{ $json.is_arctic }}"
              },
              {
                "name": "arctic_topic",
                "value": "={{ $json.arctic_topic }}"
              },
              {
                "name": "tokens_used",
                "value": "={{ $json.tokens_used }}"
              },
              {
                "name": "processed_at",
                "value": "={{ $json.processed_at }}"
              }
            ]
          }
        }
      },
      "type": "@directus/n8n-nodes-directus.directus",
      "typeVersion": 1,
      "position": [
        1648,
        0
      ],
      "id": "a5b82235-cc01-497b-a388-f2d0bf09c4b4",
      "name": "Update Article with AI Response",
      "credentials": {
        "directusApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\nconst unprocessed = [];\n\nfor (const item of items) {\n  const ai = item.json.summary_ai;\n  \n  // \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0435\u0441\u043b\u0438 summary_ai \u043f\u0443\u0441\u0442\u043e\u0439, null \u0438\u043b\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443\n  if (!ai || ai.trim() === '' || ai === '\u0422\u0435\u0441\u0442 \u0431\u0435\u0437 AI') {\n    unprocessed.push(item);\n  }\n}\n\nconsole.log(`\u0412\u0441\u0435\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439: ${items.length}, \u0431\u0435\u0437 AI: ${unprocessed.length}`);\nreturn unprocessed;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        384,
        0
      ],
      "id": "0605b0c8-9072-4f3c-aa81-9f82603c6af2",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {
        "url": "http://localhost:8055/items/news",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "filter[summary_ai][_null]",
              "value": "true"
            },
            {
              "name": "limit",
              "value": "50"
            },
            {
              "name": "sort",
              "value": "-id"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer \u0412\u0430\u0448_\u043a\u043b\u044e\u0447"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        0,
        0
      ],
      "id": "e1f47a9d-d45f-46cf-ad8a-008f786bd95d",
      "name": "HTTP Request"
    },
    {
      "parameters": {
        "jsCode": "// \u0411\u0435\u0440\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 Directus API \u0438 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 data \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 items\nconst response = $input.first().json;\nconst articles = response.data || [];\n\nconsole.log(` \u041d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439: ${articles.length}`);\n\nif (articles.length === 0) {\n  console.log(' \u041d\u0435\u0442 \u0441\u0442\u0430\u0442\u0435\u0439 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c.');\n  return [];\n}\n\nreturn articles.map(article => ({ json: article }));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        208,
        0
      ],
      "id": "1b540e40-759a-4586-a693-324cbd61adba",
      "name": "Code in JavaScript1"
    }
  ],
  "connections": {
    "Schedule Trigger (24h)": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Articles": {
      "main": [
        [],
        [
          {
            "node": "Build Request Body",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Request Body": {
      "main": [
        [
          {
            "node": "AnalysAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AnalysAI": {
      "main": [
        [
          {
            "node": "Parse LLM Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse LLM Response": {
      "main": [
        [
          {
            "node": "Update Article with AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Article with AI Response": {
      "main": [
        [
          {
            "node": "Loop Over Articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Loop Over Articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Code in JavaScript1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "5168470f-3ce2-463e-be40-32adb306de88",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodeGroups": [],
  "id": "8eU5RKvezYwMN9ov",
  "tags": []
}