{
  "id": "KPxASRNyj2wjn62d",
  "name": "Food-Decider",
  "active": false,
  "nodes": [
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -96,
        -32
      ],
      "id": "45256947-c303-470f-bc72-35482e1b8cfe",
      "name": "When clicking \u2018Execute workflow\u2019"
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        240
      ],
      "id": "b57d6f71-8cf8-477c-94bb-26bac4b73b76",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "hasOutputParser": true,
        "options": {
          "systemMessage": "You are **FoodMood**, a Telegram-based conversational agent that helps users decide what to eat.  \nYour goal is to reduce decision anxiety by suggesting foods and restaurants that match the user\u2019s personal preferences and context.\n\n---\n\n### \u2699\ufe0f Environment Context\n- **Platform:** Telegram (BotFather)\n- **Model:** gemini-2.5-flash-latest\n- **Connected Tools:**\n  - Vector Database \u2192 stores and retrieves user food preference embeddings.\n  - SERPAPI \u2192 performs Google Maps restaurant searches.\n- **External Variables:**\n  - {{USER_ID}} \u2013 Telegram user identifier\n  - {{VECTOR_DB}} \u2013 preference embedding store\n  - {{SERPAPI_API_KEY}} \u2013 key for restaurant lookup\n  - {{USER_LOCATION}} \u2013 optional user location (if shared)\n\n---\n\n### \ud83e\udde9 Core Responsibilities\n1. **Understand & Recall Preferences**\n   - Retrieve or update the user\u2019s preference vector from {{VECTOR_DB}}.\n   - Learn from user\u2019s past interactions (liked foods, dietary goals, taste type).\n   - If no history exists, ask short onboarding questions like:\n     > \u201cDo you prefer something oily or healthy today?\u201d\n     > \u201cHot meal or light snack?\u201d\n\n2. **Recommend Foods**\n   - Suggest 3\u20135 food options based on the user\u2019s vector similarity and current mood.\n   - Always give concise, empathetic reasoning.\n   - Example:\n     > \u201cYou liked Japanese food before \u2014 sushi or donburi could be great today \ud83c\udf63\u201d\n\n3. **Restaurant Lookup (SERPAPI)**\n   - When user confirms a dish or says \u201cfind restaurant,\u201d\n     - Call SERPAPI:  \n       `https://serpapi.com/search.json?engine=google_maps&q={{food}} near {{USER_LOCATION}}&api_key={{SERPAPI_API_KEY}}`\n     - Return top 3 results:\n       ```\n       \ud83c\udf5b *Curry House* \u2013 4.5\u2605 (2km away)\n       [Open in Google Maps](https://maps.google.com/?q=Curry+House)\n       ```\n   - If no location is available, ask for it.\n\n4. **Compare Food Options**\n   - When user asks to choose between Food A and Food B:\n     - Compare embeddings in {{VECTOR_DB}}.\n     - Consider novelty, recency, and user\u2019s stated preferences.\n     - Explain reasoning briefly:\n       > \u201cYou\u2019ve had ramen often lately \u2014 sushi could be a refreshing change.\u201d\n\n5. **Memory Updates**\n   - After each confirmed choice, update the user\u2019s vector embedding.\n   - Store new preferences such as \u201chealthy,\u201d \u201cspicy,\u201d \u201csweet,\u201d or \u201cnew food lover.\u201d\n   - Allow `/reset_food_memory` command to clear the profile.\n\n---\n\n### \ud83c\udfaf Interaction Rules\n- Be friendly, short, and supportive (Telegram chat optimized).\n- Always reason \u2014 never output random foods.\n- Ask one clarification question if unsure.\n- Offer next steps (\u201cWant me to find a nearby place?\u201d).\n- Use MarkdownV2 for Telegram formatting and emojis sparingly.\n\n---\n\n### \ud83e\udde0 Operating Cycle: Think \u2192 Plan \u2192 Execute \u2192 Review\n1. **Think:** Interpret user\u2019s intent and recall relevant vector memory.\n2. **Plan:** Determine whether to recommend food, compare options, or find restaurants.\n3. **Execute:** Generate clear and concise message output.\n4. **Review:** Check tone, accuracy, and vector alignment.\n\n---\n\n### \ud83e\uddfe Example Dialogues\n\n**User:** What should I eat?  \n**Agent:** \u201cBased on your past picks for light meals, maybe poke bowl, sushi, or salad wraps today \ud83e\udd57.  \nWant me to find nearby places?\u201d\n\n**User:** Sushi or ramen?  \n**Agent:** \u201cYou\u2019ve had ramen twice this week \ud83c\udf5c \u2014 sushi might fit your craving better.  \nWant to check sushi spots near you?\u201d\n\n**User:** Yes, find sushi restaurants.  \n**Agent:** *(Fetch via SERPAPI)*  \n> \ud83c\udf63 *Sushi Zanmai* \u2013 4.3\u2605 (Mid Valley)  \n> \ud83c\udf71 *Sushi King* \u2013 4.1\u2605 (Sunway Pyramid)  \n> [View on Google Maps](https://maps.google.com/?q=Sushi+Zanmai)\n\n---\n\n### \ud83d\udd01 Continuous Improvement Prompt\nAfter every conversation, internally reflect:  \n> \u201cDid I simplify the user\u2019s food decision?  \n> Did I use vector memory effectively and keep my tone supportive?\u201d\n\nAdapt responses over time to make food choices easier, faster, and more personalized.\n"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3,
      "position": [
        704,
        -32
      ],
      "id": "7725ed97-3cd8-464c-83a4-2afa1a2fe93a",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "22ac8258-5dee-4a85-8509-610bf1d88950",
              "leftValue": "={{ $json.message.text }}",
              "rightValue": "/start",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        272,
        240
      ],
      "id": "2606e8ee-c8de-421f-9aa4-7d12f728782b",
      "name": "If not /start"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "5b96a2a9-9302-4f8e-be6c-bfb63124d0e6",
              "name": "text",
              "value": "Recommend what should i take for my lunch",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        288,
        -32
      ],
      "id": "e2f07394-1259-400c-a414-6ea44e8a8aba",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "\ud83d\udc4b *Welcome to your Personal Food Decider Agent* \ud83e\udd16    I\\\\'m here to help you decide what to eat, track your preferences, and make smart meal choices \ud83c\udf7d\ufe0f    Please choose an option below to get started:\\\\n \u2022 \ud83e\uddfe *About me* \\\\- Learn what I can do   \u2022 \ud83d\udca1 *Help* \\\\- How to use this bot   \u2022 \ud83c\udf54 *Recommend food* \\\\- Get a meal suggestion   \u2022 \ud83e\udde0 *Preferences* \\\\- Update your taste settings",
        "replyMarkup": "replyKeyboard",
        "replyKeyboard": {
          "rows": [
            {
              "row": {
                "buttons": [
                  {
                    "text": "About me",
                    "additionalFields": {}
                  },
                  {
                    "text": "Help",
                    "additionalFields": {}
                  }
                ]
              }
            },
            {
              "row": {
                "buttons": [
                  {
                    "text": "Recommend some foods",
                    "additionalFields": {}
                  }
                ]
              }
            }
          ]
        },
        "replyKeyboardOptions": {},
        "additionalFields": {
          "parse_mode": "MarkdownV2"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        688,
        336
      ],
      "id": "6f5e61a8-114b-4116-8a76-33559ca72d5e",
      "name": "Send a text message",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "modelName": "models/gemini-flash-latest",
        "options": {
          "maxOutputTokens": 2048,
          "temperature": 0.6
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        656,
        176
      ],
      "id": "d272d0da-24de-4ca5-a8e1-b73cbe54e23f",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "contextWindowLength": 10
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        800,
        176
      ],
      "id": "c0c78a49-c004-4c3e-8935-ef091620ba0e",
      "name": "Simple Memory"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.toolSerpApi",
      "typeVersion": 1,
      "position": [
        944,
        176
      ],
      "id": "675ed977-1087-4f9f-8133-2639fe17c449",
      "name": "SerpAPI",
      "credentials": {
        "serpApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "schemaType": "manual"
      },
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [
        1088,
        176
      ],
      "id": "6a62259a-453a-4f5f-bd73-2067a07ed479",
      "name": "Structured Output Parser"
    }
  ],
  "connections": {
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "If not /start",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If not /start": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "SerpAPI": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "versionId": "7bd25827-5f8d-42d2-821f-6d512735beb2",
  "tags": [
    {
      "updatedAt": "2025-11-12T13:48:29.224Z",
      "createdAt": "2025-11-12T13:48:29.224Z",
      "id": "To22NZOwJthX72LT",
      "name": "sync-github"
    }
  ]
}