{
  "name": "ZEP Memory",
  "nodes": [
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.message.text }}",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2,
      "position": [
        220,
        -560
      ],
      "id": "541507eb-abde-478e-9960-567439f41475",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        -560
      ],
      "id": "210ce106-4b4e-40e6-9aff-abd151a33dd6",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "={{ $json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        580,
        -560
      ],
      "id": "03069cee-447d-41d3-95b1-d98f0445ad3c",
      "name": "Send a text message",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        -20,
        0
      ],
      "id": "58415b2c-bed0-447a-9009-c825668bfd94",
      "name": "Telegram Trigger1",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "disabled": true
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger1').item.json.message.chat.id }}",
        "text": "={{ $('AI Agent 2').item.json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1140,
        0
      ],
      "id": "6c1bc09a-f627-4719-9304-8c28fef7c264",
      "name": "Send a text message1",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// n8n Code Node\n// This code extracts all facts from the JSON structure\n\n// Get the input data\nconst items = $input.all();\nconst facts = [];\n\n// Process each item\nfor (const item of items) {\n  try {\n    // Parse the data string if it exists\n    if (item.json.data) {\n      const parsedData = JSON.parse(item.json.data);\n      \n      // Check if edges array exists\n      if (parsedData.edges && Array.isArray(parsedData.edges)) {\n        // Extract facts from each edge\n        parsedData.edges.forEach(edge => {\n          if (edge.fact) {\n            facts.push(edge.fact);\n          }\n        });\n      }\n    }\n  } catch (error) {\n    // Handle parsing errors\n    console.error('Error parsing data:', error);\n  }\n}\n\n// Return all facts as an array in a single item\nreturn [{\n  json: {\n    facts: facts\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        80
      ],
      "id": "5ef7ad9d-9fc9-49a9-b716-6abd508e67cc",
      "name": "Code"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('Telegram Trigger1').item.json.message.text }}",
        "options": {
          "systemMessage": "=You are a helpful assistant.\n\nHere is some additional information about Nate:\n{{ $json.facts.join(\"\\n\") }}\n\n5 most recent interactions with Nate:\n{{ $json.conversations.join(\"\\n\\n\")}}"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2,
      "position": [
        620,
        0
      ],
      "id": "4ce5948e-9f07-4ff4-82bc-f0a722ce7f51",
      "name": "AI Agent 2"
    },
    {
      "parameters": {
        "url": "=https://api.getzep.com/api/v2/sessions/{{ $json.message.chat.id }}/messages",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zepApi",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "10"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        160,
        -80
      ],
      "id": "6e2c0c5e-304d-45b2-b946-83855db03a57",
      "name": "Context Window",
      "credentials": {
        "zepApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.getzep.com/api/v2/graph/search",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zepApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n  \"query\": \"{{ $json.message.text }}\",\n  \"scope\": \"edges\",\n  \"limit\": 3,\n  \"search_filters\": {\n    \"min_relevance\": 0.7\n  }\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        160,
        80
      ],
      "id": "4508f733-d001-499b-8828-11a191282a1b",
      "name": "User Graph",
      "credentials": {
        "zepApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Loop through each item\nfor (const item of $input.all()) {\n  // Parse the JSON data\n  const jsonData = JSON.parse(item.json.data);\n  const messages = jsonData.messages;\n  \n  // Array to store formatted message pairs\n  const messagePairs = [];\n  \n  // Process messages in pairs (Human followed by AI)\n  for (let i = 0; i < messages.length; i++) {\n    const message = messages[i];\n    \n    // Look for Human messages\n    if (message.role === \"Human\" && message.role_type === \"user\") {\n      // Check if there's a corresponding AI response\n      if (i + 1 < messages.length && messages[i + 1].role === \"AI\" && messages[i + 1].role_type === \"assistant\") {\n        // Format the pair\n        const pair = `Human: ${message.content}\\nAI: ${messages[i + 1].content}`;\n        messagePairs.push(pair);\n        \n        // Skip the AI message in the next iteration since we've already processed it\n        i++;\n      } else {\n        // If no AI response, just add the human message\n        messagePairs.push(`Human: ${message.content}`);\n      }\n    } else if (message.role === \"AI\" && message.role_type === \"assistant\") {\n      // Handle standalone AI messages (shouldn't happen in normal conversation flow)\n      messagePairs.push(`AI: ${message.content}`);\n    }\n  }\n  \n  // Return all pairs as a single array\n  return [{\n    json: {\n      conversations: messagePairs\n    }\n  }];\n}"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        -80
      ],
      "id": "8b7169e3-e930-49e4-8969-158a52247a81",
      "name": "Code1"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        460,
        0
      ],
      "id": "ca50e57e-f1a8-447c-99e7-8db833bd7d9d",
      "name": "Merge"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.getzep.com/api/v2/sessions/{{ $('Telegram Trigger1').item.json.message.chat.id }}/memory",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zepApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n  \"session_id\": \"{{ $('Telegram Trigger1').item.json.message.chat.id }}\",\n  \"messages\": [\n    {\n      \"role_type\": \"user\",\n      \"content\": \"{{ $('Telegram Trigger1').item.json.message.text }}\"\n    },\n    {\n      \"role_type\": \"assistant\",\n      \"content\": \"{{ $json.output.replace(/\\n/g, '').replace(/\"/g, '') }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        940,
        0
      ],
      "id": "6aa1334a-b036-4c8f-943b-1bdb8293e5ec",
      "name": "Add Memory",
      "credentials": {
        "zepApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.2,
      "position": [
        -20,
        480
      ],
      "id": "16f6bd19-c4b9-4480-89bb-e58583f5e78d",
      "name": "Telegram Trigger2",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "disabled": true
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger2').item.json.message.chat.id }}",
        "text": "={{ $('AI Agent 3').item.json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1000,
        480
      ],
      "id": "dd14c87f-9583-472f-86d3-5ff12ba4ec19",
      "name": "Send a text message2",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// n8n Code Node\n// This code extracts all facts from the JSON structure\n\n// Get the input data\nconst items = $input.all();\nconst facts = [];\n\n// Process each item\nfor (const item of items) {\n  try {\n    // Parse the data string if it exists\n    if (item.json.data) {\n      const parsedData = JSON.parse(item.json.data);\n      \n      // Check if edges array exists\n      if (parsedData.edges && Array.isArray(parsedData.edges)) {\n        // Extract facts from each edge\n        parsedData.edges.forEach(edge => {\n          if (edge.fact) {\n            facts.push(edge.fact);\n          }\n        });\n      }\n    }\n  } catch (error) {\n    // Handle parsing errors\n    console.error('Error parsing data:', error);\n  }\n}\n\n// Return all facts as an array in a single item\nreturn [{\n  json: {\n    facts: facts\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        300,
        480
      ],
      "id": "609694f0-51d1-4e18-8a9c-b6283695136a",
      "name": "Code2"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.getzep.com/api/v2/graph/search",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zepApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n  \"query\": \"{{ $json.message.text }}\",\n  \"scope\": \"edges\",\n  \"limit\": 3,\n  \"search_filters\": {\n    \"min_relevance\": 0.7\n  }\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        140,
        480
      ],
      "id": "53375e1f-a339-4da1-8afd-afead4487874",
      "name": "User Graph1",
      "credentials": {
        "zepApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $('Telegram Trigger2').item.json.message.chat.id }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1.3,
      "position": [
        580,
        680
      ],
      "id": "13e2b02b-7e35-4573-99e4-552cb939a82d",
      "name": "Postgres Chat Memory",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "# Zep Memory\nContext & User Graph\n",
        "height": 500,
        "width": 940,
        "color": 2
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -120,
        -700
      ],
      "id": "3c56fef7-8976-4268-a7c0-f36fd02928ce",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        200,
        -380
      ],
      "id": "87aa689c-ce1e-4d94-8ecf-4beaaa742f08",
      "name": "GPT 4.1 mini",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        600,
        180
      ],
      "id": "be8992db-c837-453a-b4b7-0a1830fc950e",
      "name": "GPT 4.1 mini1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        440,
        680
      ],
      "id": "06dc2089-155d-48f0-8188-a518c562a251",
      "name": "GPT 4.1 mini2",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('Telegram Trigger2').item.json.message.text }}",
        "options": {
          "systemMessage": "=You are a helpful assistant.\n\nHere is some additional information about Nate:\n{{ $json.facts.join(\"\\n\") }}"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2,
      "position": [
        500,
        480
      ],
      "id": "04dc87f1-4a5d-41b4-ba84-6a09961094eb",
      "name": "AI Agent 3"
    },
    {
      "parameters": {
        "content": "# Zep Memory (HTTP)\nContext & User Graph\n",
        "height": 500,
        "width": 1480,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -120,
        -180
      ],
      "id": "bfcf0335-be1a-4f3a-ade8-2a07fe78c7cc",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "# Zep & Postgres Hybrid\nContext & User Graph\n",
        "height": 500,
        "width": 1360,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -120,
        340
      ],
      "id": "e73b68c0-ae8c-41d4-95e3-5ba58360fcca",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "=1"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryZep",
      "typeVersion": 1.3,
      "position": [
        400,
        -380
      ],
      "id": "f8b87230-812e-421c-8bb4-3a3c12896964",
      "name": "Zep",
      "credentials": {
        "zepApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $('Telegram Trigger').item.json.message.chat.id }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        940,
        -380
      ],
      "id": "fcdcdeba-4193-454f-8cef-38d5dba2e984",
      "name": "Simple Memory"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.getzep.com/api/v2/sessions/{{ $('Telegram Trigger2').item.json.message.chat.id }}/memory",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zepApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"user_id\": \"zep_c6b8b1f0611f69464c860b3ae885639e022d1c54b59ffe82d16faf9c08cc24b0\",\n  \"session_id\": \"{{ $('Telegram Trigger2').item.json.message.chat.id }}\",\n  \"messages\": [\n    {\n      \"role_type\": \"user\",\n      \"content\": \"{{ $('Telegram Trigger2').item.json.message.text }}\"\n    },\n    {\n      \"role_type\": \"assistant\",\n      \"content\": \"{{ $json.output.replace(/\\n/g, '').replace(/\"/g, '') }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        820,
        480
      ],
      "id": "7b0547f0-4f8d-4b93-9250-be3f39ec5b52",
      "name": "Add Memory1",
      "credentials": {
        "zepApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "# \ud83d\udee0\ufe0f Setup Guide  \n**Author:** [Nate Herk](https://www.youtube.com/@nateherk)\n\nFollow the steps below to get this workflow up and running:\n\n### \u2705 Step 1: Set Up Your [ZEP](https://www.getzep.com/) Account  \nHead to [ZEP](https://www.getzep.com/) and create a free account. This gives you access to your API key.  \nOnce you have your key:  \n- Plug it into the ZEP Memory Module in n8n.  \n- You can also reuse this credential in HTTP Request nodes that call ZEP\u2019s API.\n\n### \u2705 Step 2: Connect a Chat Model  \nHook up a chat model to your AI agents to power conversations.  \nOptions include:  \n- [OpenRouter](https://openrouter.ai/) \u2013 connect your OpenRouter API key.  \n- Or use any other model provider of your choice.\n\n### \u2705 Step 3: Connect Telegram (Optional)  \nWant to chat with your agents via Telegram?  \n- Add your Telegram credentials in n8n so your agents can send/receive messages there.\n\n### \u2705 Step 4: Add Your Postgres Credential  \nIn hybrid workflows that combine ZEP + Postgres, plug in your Postgres credentials.  \n- This helps maintain a solid context window across memory systems.\n\n### \ud83d\udca1 Final Step: Start Testing & Exploring  \n- Check token usage.  \n- Explore your user graph in ZEP.  \n- Fine-tune your agents.  \n- Happy automating!\n",
        "height": 780,
        "width": 780
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -920,
        -700
      ],
      "id": "e46332bd-ddda-4c73-b0e6-d8a5faedda22",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "content": "## Ew... simple memory",
        "height": 300,
        "width": 300,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        840,
        -500
      ],
      "id": "1b8398c5-f2bd-476e-8cb7-2eac3f7285a3",
      "name": "Sticky Note4"
    }
  ],
  "connections": {
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger1": {
      "main": [
        [
          {
            "node": "Context Window",
            "type": "main",
            "index": 0
          },
          {
            "node": "User Graph",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "User Graph": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Context Window": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "AI Agent 2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent 2": {
      "main": [
        [
          {
            "node": "Add Memory",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Memory": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger2": {
      "main": [
        [
          {
            "node": "User Graph1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code2": {
      "main": [
        [
          {
            "node": "AI Agent 3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "User Graph1": {
      "main": [
        [
          {
            "node": "Code2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent 3",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "GPT 4.1 mini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "GPT 4.1 mini1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent 2",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "GPT 4.1 mini2": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent 3",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent 3": {
      "main": [
        [
          {
            "node": "Add Memory1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Zep": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        []
      ]
    },
    "Add Memory1": {
      "main": [
        [
          {
            "node": "Send a text message2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e8c7f5bb-22d9-4b81-90d6-e18e413c4092",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "GxMydqOT8W74wJW7",
  "tags": []
}