{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Building A Chatbot\n",
    "In this video We'll go over an example of how to design and implement an LLM-powered chatbot. This chatbot will be able to have a conversation and remember previous interactions.\n",
    "\n",
    "Note that this chatbot that we build will only use the language model to have a conversation. There are several other related concepts that you may be looking for:\n",
    "\n",
    "- Conversational RAG: Enable a chatbot experience over an external source of data\n",
    "- Agents: Build a chatbot that can take actions\n",
    "\n",
    "This video tutorial will cover the basics which will be helpful for those two more advanced topics."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'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'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "load_dotenv() ## aloading all the environment variable\n",
    "\n",
    "groq_api_key=os.getenv(\"GROQ_API_KEY\")\n",
    "groq_api_key\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ChatGroq(client=<groq.resources.chat.completions.Completions object at 0x0000025A1B319D20>, async_client=<groq.resources.chat.completions.AsyncCompletions object at 0x0000025A1B31A9E0>, model_name='Gemma2-9b-It', groq_api_key=SecretStr('**********'))"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_groq import ChatGroq\n",
    "model=ChatGroq(model=\"Gemma2-9b-It\",groq_api_key=groq_api_key)\n",
    "model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content=\"Hello Krish! It's nice to meet you. \\n\\nAs a Chief AI Engineer, what kind of projects are you working on these days? \\n\\nI'm always eager to learn more about the exciting work being done in the field of AI.\\n\", response_metadata={'token_usage': {'completion_tokens': 55, 'prompt_tokens': 27, 'total_tokens': 82, 'completion_time': 0.11, 'prompt_time': 0.003535862, 'queue_time': None, 'total_time': 0.113535862}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_10c08bf97d', 'finish_reason': 'stop', 'logprobs': None}, id='run-218d4449-8b1a-431c-926f-1eb903fecebf-0', usage_metadata={'input_tokens': 27, 'output_tokens': 55, 'total_tokens': 82})"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.messages import HumanMessage\n",
    "model.invoke([HumanMessage(content=\"Hi , My name is Krish and I am a Chief AI Engineer\")])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content=\"You said your name is Krish and you are a Chief AI Engineer! \\n\\nIs there anything else you'd like me to remember about you?  \\n\\n\", response_metadata={'token_usage': {'completion_tokens': 35, 'prompt_tokens': 102, 'total_tokens': 137, 'completion_time': 0.07, 'prompt_time': 0.005276236, 'queue_time': None, 'total_time': 0.07527623600000001}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_e238d2cf52', 'finish_reason': 'stop', 'logprobs': None}, id='run-69203ab2-a54d-43ee-9676-f68367cdac82-0', usage_metadata={'input_tokens': 102, 'output_tokens': 35, 'total_tokens': 137})"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.messages import AIMessage\n",
    "model.invoke(\n",
    "    [\n",
    "        HumanMessage(content=\"Hi , My name is Krish and I am a Chief AI Engineer\"),\n",
    "        AIMessage(content=\"Hello Krish! It's nice to meet you. \\n\\nAs a Chief AI Engineer, what kind of projects are you working on these days? \\n\\nI'm always eager to learn more about the exciting work being done in the field of AI.\\n\"),\n",
    "        HumanMessage(content=\"Hey What's my name and what do I do?\")\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Message History\n",
    "We can use a Message History class to wrap our model and make it stateful. This will keep track of inputs and outputs of the model, and store them in some datastore. Future interactions will then load those messages and pass them into the chain as part of the input. Let's see how to use this!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: langchain_community in e:\\udemy final\\langchain\\venv\\lib\\site-packages (0.2.5)\n",
      "Requirement already satisfied: PyYAML>=5.3 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (6.0.1)\n",
      "Requirement already satisfied: SQLAlchemy<3,>=1.4 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (2.0.30)\n",
      "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (3.9.5)\n",
      "Requirement already satisfied: dataclasses-json<0.7,>=0.5.7 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (0.6.7)\n",
      "Requirement already satisfied: langchain<0.3.0,>=0.2.5 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (0.2.5)\n",
      "Requirement already satisfied: langchain-core<0.3.0,>=0.2.7 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (0.2.10)\n",
      "Requirement already satisfied: langsmith<0.2.0,>=0.1.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (0.1.77)\n",
      "Requirement already satisfied: numpy<2,>=1 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (1.26.4)\n",
      "Requirement already satisfied: requests<3,>=2 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (2.31.0)\n",
      "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain_community) (8.4.1)\n",
      "Requirement already satisfied: aiosignal>=1.1.2 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.3.1)\n",
      "Requirement already satisfied: attrs>=17.3.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (23.2.0)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.4.1)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (6.0.5)\n",
      "Requirement already satisfied: yarl<2.0,>=1.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.9.4)\n",
      "Requirement already satisfied: async-timeout<5.0,>=4.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (4.0.3)\n",
      "Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from dataclasses-json<0.7,>=0.5.7->langchain_community) (3.21.3)\n",
      "Requirement already satisfied: typing-inspect<1,>=0.4.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from dataclasses-json<0.7,>=0.5.7->langchain_community) (0.9.0)\n",
      "Requirement already satisfied: langchain-text-splitters<0.3.0,>=0.2.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain<0.3.0,>=0.2.5->langchain_community) (0.2.1)\n",
      "Requirement already satisfied: pydantic<3,>=1 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain<0.3.0,>=0.2.5->langchain_community) (1.10.13)\n",
      "Requirement already satisfied: jsonpatch<2.0,>=1.33 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain-core<0.3.0,>=0.2.7->langchain_community) (1.33)\n",
      "Requirement already satisfied: packaging<25,>=23.2 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langchain-core<0.3.0,>=0.2.7->langchain_community) (24.1)\n",
      "Requirement already satisfied: orjson<4.0.0,>=3.9.14 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from langsmith<0.2.0,>=0.1.0->langchain_community) (3.10.5)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from requests<3,>=2->langchain_community) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from requests<3,>=2->langchain_community) (3.7)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from requests<3,>=2->langchain_community) (2.2.2)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from requests<3,>=2->langchain_community) (2024.6.2)\n",
      "Requirement already satisfied: typing-extensions>=4.6.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from SQLAlchemy<3,>=1.4->langchain_community) (4.12.2)\n",
      "Requirement already satisfied: greenlet!=0.4.17 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from SQLAlchemy<3,>=1.4->langchain_community) (3.0.3)\n",
      "Requirement already satisfied: jsonpointer>=1.9 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from jsonpatch<2.0,>=1.33->langchain-core<0.3.0,>=0.2.7->langchain_community) (3.0.0)\n",
      "Requirement already satisfied: mypy-extensions>=0.3.0 in e:\\udemy final\\langchain\\venv\\lib\\site-packages (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain_community) (1.0.0)\n"
     ]
    }
   ],
   "source": [
    "!pip install langchain_community"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.chat_message_histories import ChatMessageHistory\n",
    "from langchain_core.chat_history import BaseChatMessageHistory\n",
    "from langchain_core.runnables.history import RunnableWithMessageHistory\n",
    "\n",
    "store={}\n",
    "\n",
    "def get_session_history(session_id:str)->BaseChatMessageHistory:\n",
    "    if session_id not in store:\n",
    "        store[session_id]=ChatMessageHistory()\n",
    "    return store[session_id]\n",
    "\n",
    "with_message_history=RunnableWithMessageHistory(model,get_session_history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "config={\"configurable\":{\"session_id\":\"chat1\"}}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "response=with_message_history.invoke(\n",
    "    [HumanMessage(content=\"Hi , My name is Krish and I am a Chief AI Engineer\")],\n",
    "    config=config\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"Hi Krish!\\n\\nIt's great to meet you.  Being a Chief AI Engineer is a fascinating role. What kind of projects are you currently working on?  I'm always interested in hearing about the cutting edge of AI development.  \\n\\n\""
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='Your name is Krish.  \\n\\nI remember that you introduced yourself at the beginning of our conversation. 😊  \\n\\n\\n\\nIs there anything else I can help you with?\\n', response_metadata={'token_usage': {'completion_tokens': 36, 'prompt_tokens': 173, 'total_tokens': 209, 'completion_time': 0.072, 'prompt_time': 0.008576801, 'queue_time': None, 'total_time': 0.08057680099999999}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_e238d2cf52', 'finish_reason': 'stop', 'logprobs': None}, id='run-e4631e90-20b0-4a98-9372-5198792a957a-0', usage_metadata={'input_tokens': 173, 'output_tokens': 36, 'total_tokens': 209})"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "with_message_history.invoke(\n",
    "    [HumanMessage(content=\"What's my name?\")],\n",
    "    config=config,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"As an AI, I have no memory of past conversations and don't know your name. If you'd like to tell me, I'd be happy to use it! 😊  \\n\\n\""
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## change the config-->session id\n",
    "config1={\"configurable\":{\"session_id\":\"chat2\"}}\n",
    "response=with_message_history.invoke(\n",
    "    [HumanMessage(content=\"Whats my name\")],\n",
    "    config=config1\n",
    ")\n",
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"Hi John, it's nice to meet you! \\n\\nWhat can I do for you today?  \\n\""
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response=with_message_history.invoke(\n",
    "    [HumanMessage(content=\"Hey My name is John\")],\n",
    "    config=config1\n",
    ")\n",
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Your name is John!  I remember. 😊  \\n\\nIs there anything else I can help you with?\\n'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response=with_message_history.invoke(\n",
    "    [HumanMessage(content=\"Whats my name\")],\n",
    "    config=config1\n",
    ")\n",
    "response.content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prompt templates\n",
    "Prompt Templates help to turn raw user information into a format that the LLM can work with. In this case, the raw user input is just a message, which we are passing to the LLM. Let's now make that a bit more complicated. First, let's add in a system message with some custom instructions (but still taking messages as input). Next, we'll add in more input besides just the messages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholder\n",
    "prompt=ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\"system\",\"You are a helpful assistant.Amnswer all the question to the nest of your ability\"),\n",
    "        MessagesPlaceholder(variable_name=\"messages\")\n",
    "    ]\n",
    ")\n",
    "\n",
    "chain=prompt|model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content=\"Hi Krish, it's nice to meet you! 👋\\n\\nHow can I help you today? 😊 \\n\", response_metadata={'token_usage': {'completion_tokens': 25, 'prompt_tokens': 36, 'total_tokens': 61, 'completion_time': 0.05, 'prompt_time': 0.003914296, 'queue_time': None, 'total_time': 0.053914296}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_e238d2cf52', 'finish_reason': 'stop', 'logprobs': None}, id='run-1f9187c3-4e8b-4ea5-809f-5c9d06d382dd-0', usage_metadata={'input_tokens': 36, 'output_tokens': 25, 'total_tokens': 61})"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke({\"messages\":[HumanMessage(content=\"Hi My name is Krish\")]})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "with_message_history=RunnableWithMessageHistory(chain,get_session_history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content=\"Hello Krish, it's nice to meet you! \\n\\nHow can I help you today? 😊  \\n\\n\", response_metadata={'token_usage': {'completion_tokens': 26, 'prompt_tokens': 36, 'total_tokens': 62, 'completion_time': 0.052, 'prompt_time': 0.002896296, 'queue_time': None, 'total_time': 0.054896296}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_10c08bf97d', 'finish_reason': 'stop', 'logprobs': None}, id='run-3fb00972-77a2-4d2e-91b0-e1490fc7289d-0', usage_metadata={'input_tokens': 36, 'output_tokens': 26, 'total_tokens': 62})"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "config = {\"configurable\": {\"session_id\": \"chat3\"}}\n",
    "response=with_message_history.invoke(\n",
    "    [HumanMessage(content=\"Hi My name is Krish\")],\n",
    "    config=config\n",
    ")\n",
    "\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Your name is Krish.  I remember! 😄 \\n\\nIs there anything else I can help you with?\\n'"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response = with_message_history.invoke(\n",
    "    [HumanMessage(content=\"What's my name?\")],\n",
    "    config=config,\n",
    ")\n",
    "\n",
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Add more complexity\n",
    "\n",
    "prompt = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\n",
    "            \"system\",\n",
    "            \"You are a helpful assistant. Answer all questions to the best of your ability in {language}.\",\n",
    "        ),\n",
    "        MessagesPlaceholder(variable_name=\"messages\"),\n",
    "    ]\n",
    ")\n",
    "\n",
    "chain = prompt | model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'नमस्ते कृष्ण! 👋  \\n\\nमुझे आपसे मिलकर अच्छा लगा।  😊 \\n\\nआप क्या करना चाहते हैं? \\n'"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response=chain.invoke({\"messages\":[HumanMessage(content=\"Hi My name is Krish\")],\"language\":\"Hindi\"})\n",
    "response.content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's now wrap this more complicated chain in a Message History class. This time, because there are multiple keys in the input, we need to specify the correct key to use to save the chat history."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "with_message_history=RunnableWithMessageHistory(\n",
    "    chain,\n",
    "    get_session_history,\n",
    "    input_messages_key=\"messages\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'नमस्ते कृष! 😊 \\n\\nतुम्हें कैसे हो? क्या मैं तुमकी कोई मदद कर सकता हूँ?\\n'"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "config = {\"configurable\": {\"session_id\": \"chat4\"}}\n",
    "repsonse=with_message_history.invoke(\n",
    "    {'messages': [HumanMessage(content=\"Hi,I am Krish\")],\"language\":\"Hindi\"},\n",
    "    config=config\n",
    ")\n",
    "repsonse.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "response = with_message_history.invoke(\n",
    "    {\"messages\": [HumanMessage(content=\"whats my name?\")], \"language\": \"Hindi\"},\n",
    "    config=config,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'आपका नाम कृष है। 😊 \\n'"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response.content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Managing the Conversation History\n",
    "One important concept to understand when building chatbots is how to manage conversation history. If left unmanaged, the list of messages will grow unbounded and potentially overflow the context window of the LLM. Therefore, it is important to add a step that limits the size of the messages you are passing in.\n",
    "'trim_messages' helper to reduce how many messages we're sending to the model. The trimmer allows us to specify how many tokens we want to keep, along with other parameters like if we want to always keep the system message and whether to allow partial messages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[SystemMessage(content=\"you're a good assistant\"),\n",
       " HumanMessage(content='I like vanilla ice cream'),\n",
       " AIMessage(content='nice'),\n",
       " HumanMessage(content='whats 2 + 2'),\n",
       " AIMessage(content='4'),\n",
       " HumanMessage(content='thanks'),\n",
       " AIMessage(content='no problem!'),\n",
       " HumanMessage(content='having fun?'),\n",
       " AIMessage(content='yes!')]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.messages import SystemMessage,trim_messages\n",
    "trimmer=trim_messages(\n",
    "    max_tokens=45,\n",
    "    strategy=\"last\",\n",
    "    token_counter=model,\n",
    "    include_system=True,\n",
    "    allow_partial=False,\n",
    "    start_on=\"human\"\n",
    ")\n",
    "messages = [\n",
    "    SystemMessage(content=\"you're a good assistant\"),\n",
    "    HumanMessage(content=\"hi! I'm bob\"),\n",
    "    AIMessage(content=\"hi!\"),\n",
    "    HumanMessage(content=\"I like vanilla ice cream\"),\n",
    "    AIMessage(content=\"nice\"),\n",
    "    HumanMessage(content=\"whats 2 + 2\"),\n",
    "    AIMessage(content=\"4\"),\n",
    "    HumanMessage(content=\"thanks\"),\n",
    "    AIMessage(content=\"no problem!\"),\n",
    "    HumanMessage(content=\"having fun?\"),\n",
    "    AIMessage(content=\"yes!\"),\n",
    "]\n",
    "trimmer.invoke(messages)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"As an AI, I don't have access to your personal preferences like your favorite ice cream flavor.  \\n\\nWhat's your favorite ice cream? 😊🍦\\n\""
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from operator import itemgetter\n",
    "\n",
    "from langchain_core.runnables import RunnablePassthrough\n",
    "\n",
    "chain=(\n",
    "    RunnablePassthrough.assign(messages=itemgetter(\"messages\")|trimmer)\n",
    "    | prompt\n",
    "    | model\n",
    "    \n",
    ")\n",
    "\n",
    "response=chain.invoke(\n",
    "    {\n",
    "    \"messages\":messages + [HumanMessage(content=\"What ice cream do i like\")],\n",
    "    \"language\":\"English\"\n",
    "    }\n",
    ")\n",
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'You asked \"whats 2 + 2\" 😊  \\n\\n\\n\\n'"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response = chain.invoke(\n",
    "    {\n",
    "        \"messages\": messages + [HumanMessage(content=\"what math problem did i ask\")],\n",
    "        \"language\": \"English\",\n",
    "    }\n",
    ")\n",
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Lets wrap this in the MEssage History\n",
    "with_message_history = RunnableWithMessageHistory(\n",
    "    chain,\n",
    "    get_session_history,\n",
    "    input_messages_key=\"messages\",\n",
    ")\n",
    "config={\"configurable\":{\"session_id\":\"chat5\"}}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"As a large language model, I don't have access to past conversations or any personal information about you, including your name.  \\n\\nIf you'd like to tell me your name, I'd be happy to know! 😊  \\n\\n\""
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response = with_message_history.invoke(\n",
    "    {\n",
    "        \"messages\": messages + [HumanMessage(content=\"whats my name?\")],\n",
    "        \"language\": \"English\",\n",
    "    },\n",
    "    config=config,\n",
    ")\n",
    "\n",
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"As a large language model, I have no memory of past conversations. If you'd like to ask me a math problem, I'm happy to help! 😊  Just let me know what it is. \\n\\n\""
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "response = with_message_history.invoke(\n",
    "    {\n",
    "        \"messages\": [HumanMessage(content=\"what math problem did i ask?\")],\n",
    "        \"language\": \"English\",\n",
    "    },\n",
    "    config=config,\n",
    ")\n",
    "\n",
    "response.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
