{
 "name": "[노드 한 장] Chat Memory Manager · 내 가상 대화 마지막 한 개만 삭제",
 "nodes": [
  {
   "id": "manual",
   "name": "Run manually",
   "type": "n8n-nodes-base.manualTrigger",
   "typeVersion": 1,
   "position": [
    0,
    0
   ],
   "parameters": {}
  },
  {
   "id": "fixture",
   "name": "Create own fixture",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [
    220,
    0
   ],
   "parameters": {
    "jsCode": "const executionId=String($execution.id||''); if(!executionId)throw Error('Missing execution ID'); const owner='EP75_OWN_FIXTURE'; const sessionKey=`${owner}:${$workflow.id}:${executionId}:${Date.now()}:${Math.random().toString(36).slice(2)}`; return [{json:{sample:true,fictional:true,owner,executionId,sessionKey,userText:'가상 실습: 프로젝트 별칭은 달빛입니다.',aiText:'가상 AI 역할 샘플: 별칭 달빛을 기록했습니다.'}}];"
   }
  },
  {
   "id": "insert",
   "name": "Insert own fictional messages",
   "type": "@n8n/n8n-nodes-langchain.memoryManager",
   "typeVersion": 1.1,
   "position": [
    440,
    0
   ],
   "parameters": {
    "mode": "insert",
    "insertMode": "insert",
    "messages": {
     "messageValues": [
      {
       "type": "user",
       "message": "={{ $('Create own fixture').first().json.userText }}",
       "hideFromUI": false
      },
      {
       "type": "ai",
       "message": "={{ $('Create own fixture').first().json.aiText }}",
       "hideFromUI": false
      }
     ]
    }
   }
  },
  {
   "id": "before",
   "name": "Get own messages before delete",
   "type": "@n8n/n8n-nodes-langchain.memoryManager",
   "typeVersion": 1.1,
   "position": [
    660,
    0
   ],
   "parameters": {
    "mode": "load",
    "simplifyOutput": false,
    "options": {
     "groupMessages": true
    }
   }
  },
  {
   "id": "guard",
   "name": "Guard exact own fixture before delete",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [
    880,
    0
   ],
   "parameters": {
    "jsCode": "const f=$('Create own fixture').first().json; const j=$input.first().json; const prefix=`EP75_OWN_FIXTURE:${$workflow.id}:${$execution.id}:`; if(f.owner!=='EP75_OWN_FIXTURE'||f.executionId!==String($execution.id)||!f.sessionKey.startsWith(prefix)||!f.fictional)throw Error('STOP: not this execution own fixture'); const m=j.messages; if(!Array.isArray(m)||j.messagesCount!==2||m.length!==2||m[0]?.kwargs?.content!==f.userText||m[1]?.kwargs?.content!==f.aiText||m[0]?.id?.at(-1)!=='HumanMessage'||m[1]?.id?.at(-1)!=='AIMessage')throw Error('STOP: expected own sample contents or roles mismatch'); return [{json:{ownFixtureGuardPassed:true,beforeCount:m.length,sessionKey:f.sessionKey,expectedDeleteCount:1,fixtureOnly:true}}];"
   }
  },
  {
   "id": "delete",
   "name": "Delete last one own sample",
   "type": "@n8n/n8n-nodes-langchain.memoryManager",
   "typeVersion": 1.1,
   "position": [
    1100,
    0
   ],
   "parameters": {
    "mode": "delete",
    "deleteMode": "lastN",
    "lastMessagesCount": 1
   }
  },
  {
   "id": "after",
   "name": "Get own messages after delete",
   "type": "@n8n/n8n-nodes-langchain.memoryManager",
   "typeVersion": 1.1,
   "position": [
    1320,
    0
   ],
   "parameters": {
    "mode": "load",
    "simplifyOutput": false,
    "options": {
     "groupMessages": true
    }
   }
  },
  {
   "id": "verify",
   "name": "Verify exact before and after",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [
    1540,
    0
   ],
   "parameters": {
    "jsCode": "const f=$('Create own fixture').first().json,j=$input.first().json,g=$('Guard exact own fixture before delete').first().json; const m=j.messages; if(!g.ownFixtureGuardPassed||g.sessionKey!==f.sessionKey||!Array.isArray(m)||j.messagesCount!==1||m.length!==1||m[0]?.kwargs?.content!==f.userText||m[0]?.id?.at(-1)!=='HumanMessage')throw Error('After-delete mismatch');return [{json:{sample:true,fictional:true,modelCalls:0,beforeCount:g.beforeCount,deletedLast:1,afterCount:m.length,remainingRole:'HumanMessage',remainingText:m[0].kwargs.content,aiRoleSampleRemoved:true,guardPassed:true,sessionKeyMatches:true,outputType:'messages: array; messagesCount: number',note:'Directly authored fictional conversation, not a generated AI response'}}];"
   }
  },
  {
   "id": "memory",
   "name": "Simple Memory own runtime fixture",
   "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
   "typeVersion": 1.3,
   "position": [
    880,
    260
   ],
   "parameters": {
    "sessionIdType": "customKey",
    "sessionKey": "={{ $('Create own fixture').first().json.sessionKey }}",
    "contextWindowLength": 5
   }
  }
 ],
 "connections": {
  "Run manually": {
   "main": [
    [
     {
      "node": "Create own fixture",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Create own fixture": {
   "main": [
    [
     {
      "node": "Insert own fictional messages",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Insert own fictional messages": {
   "main": [
    [
     {
      "node": "Get own messages before delete",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Get own messages before delete": {
   "main": [
    [
     {
      "node": "Guard exact own fixture before delete",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Guard exact own fixture before delete": {
   "main": [
    [
     {
      "node": "Delete last one own sample",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Delete last one own sample": {
   "main": [
    [
     {
      "node": "Get own messages after delete",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Get own messages after delete": {
   "main": [
    [
     {
      "node": "Verify exact before and after",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Simple Memory own runtime fixture": {
   "ai_memory": [
    [
     {
      "node": "Insert own fictional messages",
      "type": "ai_memory",
      "index": 0
     },
     {
      "node": "Get own messages before delete",
      "type": "ai_memory",
      "index": 0
     },
     {
      "node": "Delete last one own sample",
      "type": "ai_memory",
      "index": 0
     },
     {
      "node": "Get own messages after delete",
      "type": "ai_memory",
      "index": 0
     }
    ]
   ]
  }
 },
 "settings": {
  "executionOrder": "v1"
 },
 "meta": {
  "templateCredsSetupCompleted": false,
  "source": "datapopcorn.ai/workflow/nodes"
 }
}