{
  "id": "ai-fitness",
  "name": "AI Fitness Gemini Orchestrator",
  "active": true,
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "ai-fitness",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1000,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const body = $json.body || {};\n\nif (!body.message || typeof body.message !== 'string' || body.message.trim() === '') {\n  throw new Error('Message is required');\n}\n\nreturn [{\n  json: {\n    message: body.message.trim(),\n    userId: body.userId || 'anonymous',\n    context: body.context || {},\n    timestamp: new Date().toISOString()\n  }\n}];\n"
      },
      "id": "parse",
      "name": "Parse & Validate",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -800,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const ctx = $json.context;\nlet contextText = '';\n\nif (typeof ctx === 'string') {\n  contextText = ctx;\n} else if (ctx && typeof ctx === 'object') {\n  if (ctx.profile) contextText += `Profile: ${JSON.stringify(ctx.profile)}\\n`;\n  if (ctx.activity) contextText += `Recent Activity: ${JSON.stringify(ctx.activity)}\\n`;\n  if (ctx.nutrition) contextText += `Nutrition Log: ${JSON.stringify(ctx.nutrition)}\\n`;\n}\n\nreturn [{\n  json: {\n    ...$json,\n    systemContext: contextText.trim()\n  }\n}];\n"
      },
      "id": "build-context",
      "name": "Build Context",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -600,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const userMsg = $json.message;\nconst context = $json.systemContext || '';\n\nconst systemPrompt = `B\u1ea1n l\u00e0 Fitness Coach RunSwim chuy\u00ean v\u1ec1 ch\u1ea1y b\u1ed9, b\u01a1i l\u1ed9i, ph\u1ee5c h\u1ed3i v\u00e0 dinh d\u01b0\u1ee1ng th\u1ec3 thao.\\n\\nQUY T\u1eaeC QUAN TR\u1eccNG:\\n1. D\u1eee LI\u1ec6U NG\u01af\u1edcI D\u00d9NG \u0111\u01b0\u1ee3c cung c\u1ea5p s\u1eb5n trong ph\u1ea7n [D\u1eef li\u1ec7u c\u00e1 nh\u00e2n] d\u01b0\u1edbi \u0111\u00e2y. H\u00c3Y D\u00d9NG d\u1eef li\u1ec7u n\u00e0y \u0111\u1ec3 c\u00e1 nh\u00e2n ho\u00e1 c\u00e2u tr\u1ea3 l\u1eddi.\\n2. TUY\u1ec6T \u0110\u1ed0I KH\u00d4NG h\u1ecfi l\u1ea1i c\u00e1c th\u00f4ng tin \u0111\u00e3 c\u00f3 (t\u00ean, tu\u1ed5i, c\u00e2n n\u1eb7ng, chi\u1ec1u cao, m\u1ee5c ti\u00eau, tr\u00ecnh \u0111\u1ed9, ho\u1ea1t \u0111\u1ed9ng g\u1ea7n \u0111\u00e2y, dinh d\u01b0\u1ee1ng).\\n3. N\u1ebfu thi\u1ebfu d\u1eef li\u1ec7u n\u00e0o, h\u00e3y \u0111\u01b0a ra gi\u1ea3 \u0111\u1ecbnh h\u1ee3p l\u00fd cho ng\u01b0\u1eddi Vi\u1ec7t Nam trung b\u00ecnh v\u00e0 tr\u1ea3 l\u1eddi ngay (kh\u00f4ng h\u1ecfi l\u1ea1i).\\n4. Tr\u1ea3 l\u1eddi NG\u1eaeN G\u1eccN, T\u1eacP TRUNG, c\u00f3 h\u00e0nh \u0111\u1ed9ng c\u1ee5 th\u1ec3. T\u1ed1i \u0111a 250 t\u1eeb tr\u1eeb khi c\u00e2u h\u1ecfi y\u00eau c\u1ea7u danh s\u00e1ch d\u00e0i.\\n5. Tr\u1ea3 l\u1eddi b\u1eb1ng ti\u1ebfng Vi\u1ec7t, gi\u1ecdng th\u00e2n thi\u1ec7n, c\u00f3 l\u1eddi khuy\u00ean an to\u00e0n (kh\u00f4ng thay th\u1ebf b\u00e1c s\u0129).\\n6. D\u00f9ng s\u1ed1 li\u1ec7u th\u1eadt trong [D\u1eef li\u1ec7u c\u00e1 nh\u00e2n] khi tr\u1ea3 l\u1eddi (v\u00ed d\u1ee5: \\\"V\u1edbi c\u00e2n n\u1eb7ng X kg c\u1ee7a b\u1ea1n...\\\").`;\n\nconst dataBlock = context\n  ? `[D\u1eef li\u1ec7u c\u00e1 nh\u00e2n]\\n${context}\\n[H\u1ebft d\u1eef li\u1ec7u c\u00e1 nh\u00e2n]`\n  : '[D\u1eef li\u1ec7u c\u00e1 nh\u00e2n] Ng\u01b0\u1eddi d\u00f9ng ch\u01b0a c\u1eadp nh\u1eadt h\u1ed3 s\u01a1. Gi\u1ea3 \u0111\u1ecbnh: ng\u01b0\u1eddi Vi\u1ec7t Nam, m\u1edbi b\u1eaft \u0111\u1ea7u t\u1eadp luy\u1ec7n. [H\u1ebft d\u1eef li\u1ec7u c\u00e1 nh\u00e2n]';\n\nconst fullPrompt = `${systemPrompt}\\n\\n${dataBlock}\\n\\nC\u00e2u h\u1ecfi c\u1ee7a ng\u01b0\u1eddi d\u00f9ng: ${userMsg}`;\n\nreturn [{\n  json: {\n    ...$json,\n    systemPrompt,\n    userPrompt: userMsg,\n    fullPrompt\n  }\n}];\n"
      },
      "id": "prompt-engineering",
      "name": "Prompt Engineering",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -400,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "__GEMINI_URL_PLACEHOLDER__",
        "sendBody": true,
        "contentType": "json",
        "bodyParameters": {
          "parameters": [
            {
              "name": "contents",
              "value": "={{ [{ parts: [{ text: $json.fullPrompt }] }] }}"
            }
          ]
        },
        "options": {
          "timeout": 60000
        }
      },
      "id": "gemini",
      "name": "Gemini API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "continueOnFail": true,
      "position": [
        -200,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const response = $json;\nconst text = response.candidates?.[0]?.content?.parts?.[0]?.text;\n\nif (!text || !text.trim()) {\n  throw new Error('Gemini API failed: ' + (response.error?.message || 'No reply'));\n}\n\nreturn [{\n  json: {\n    reply: text.trim(),\n    text: text.trim(),\n    success: true,\n    model: 'gemini-2.5-flash'\n  }\n}];\n"
      },
      "id": "output-filter",
      "name": "Output Filter",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "firstIncomingItem",
        "options": {}
      },
      "id": "respond",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        200,
        0
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Parse & Validate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Validate": {
      "main": [
        [
          {
            "node": "Build Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Context": {
      "main": [
        [
          {
            "node": "Prompt Engineering",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prompt Engineering": {
      "main": [
        [
          {
            "node": "Gemini API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini API": {
      "main": [
        [
          {
            "node": "Output Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Output Filter": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}