{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2c75da30",
   "metadata": {},
   "source": [
    "# Agent Chat with Multimodal Models: LLaVA\n",
    "\n",
    "This notebook uses **LLaVA** as an example for the multimodal feature. More information about LLaVA can be found in their [GitHub page](https://github.com/haotian-liu/LLaVA)\n",
    "\n",
    "\n",
    "This notebook contains the following information and examples:\n",
    "\n",
    "1. Setup LLaVA Model\n",
    "    - Option 1: Use [API calls from `Replicate`](#replicate)\n",
    "    - Option 2: Setup [LLaVA locally (requires GPU)](#local)\n",
    "2. Application 1: [Image Chat](#app-1)\n",
    "3. Application 2: [Figure Creator](#app-2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f51914c",
   "metadata": {},
   "source": [
    "### Before everything starts, install AutoGen with the `lmm` option\n",
    "```bash\n",
    "pip install \"autogen-agentchat[lmm]~=0.2\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b1ffe2ab",
   "metadata": {},
   "outputs": [],
   "source": [
    "# We use this variable to control where you want to host LLaVA, locally or remotely?\n",
    "# More details in the two setup options below.\n",
    "import json\n",
    "import os\n",
    "import random\n",
    "import time\n",
    "from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import requests\n",
    "from PIL import Image\n",
    "from termcolor import colored\n",
    "\n",
    "import autogen\n",
    "from autogen import Agent, AssistantAgent, ConversableAgent, UserProxyAgent\n",
    "from autogen.agentchat.contrib.llava_agent import LLaVAAgent, llava_call\n",
    "\n",
    "LLAVA_MODE = \"remote\"  # Either \"local\" or \"remote\"\n",
    "assert LLAVA_MODE in [\"local\", \"remote\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "acc4703b",
   "metadata": {},
   "source": [
    "<a id=\"replicate\"></a>\n",
    "## (Option 1, preferred) Use API Calls from Replicate [Remote]\n",
    "We can also use [Replicate](https://replicate.com/yorickvp/llava-13b/api) to use LLaVA directly, which will host the model for you.\n",
    "\n",
    "1. Run `pip install replicate` to install the package\n",
    "2. You need to get an API key from Replicate from your [account setting page](https://replicate.com/account/api-tokens)\n",
    "3. Next, copy your API token and authenticate by setting it as an environment variable:\n",
    "    `export REPLICATE_API_TOKEN=<paste-your-token-here>` \n",
    "4. You need to enter your credit card information for Replicate 🥲\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f650bf3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# pip install replicate\n",
    "# import os\n",
    "## alternatively, you can put your API key here for the environment variable.\n",
    "# os.environ[\"REPLICATE_API_TOKEN\"] = \"r8_xyz your api key goes here~\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "267ffd78",
   "metadata": {},
   "outputs": [],
   "source": [
    "if LLAVA_MODE == \"remote\":\n",
    "    import replicate\n",
    "\n",
    "    llava_config_list = [\n",
    "        {\n",
    "            \"model\": \"whatever, will be ignored for remote\",  # The model name doesn't matter here right now.\n",
    "            \"api_key\": \"None\",  # Note that you have to setup the API key with os.environ[\"REPLICATE_API_TOKEN\"]\n",
    "            \"base_url\": \"yorickvp/llava-13b:2facb4a474a0462c15041b78b1ad70952ea46b5ec6ad29583c0b29dbd4249591\",\n",
    "        }\n",
    "    ]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1805e4bd",
   "metadata": {},
   "source": [
    "<a id=\"local\"></a>\n",
    "## [Option 2] Setup LLaVA Locally\n",
    "\n",
    "\n",
    "## Install the LLaVA library\n",
    "\n",
    "Please follow the LLaVA GitHub [page](https://github.com/haotian-liu/LLaVA/) to install LLaVA.\n",
    "\n",
    "\n",
    "#### Download the package\n",
    "```bash\n",
    "git clone https://github.com/haotian-liu/LLaVA.git\n",
    "cd LLaVA\n",
    "```\n",
    "\n",
    "#### Install the inference package\n",
    "```bash\n",
    "conda create -n llava python=3.10 -y\n",
    "conda activate llava\n",
    "pip install --upgrade pip  # enable PEP 660 support\n",
    "pip install -e .\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "Some helpful packages and dependencies:\n",
    "```bash\n",
    "conda install -c nvidia cuda-toolkit\n",
    "```\n",
    "\n",
    "\n",
    "### Launch\n",
    "\n",
    "In one terminal, start the controller first:\n",
    "```bash\n",
    "python -m llava.serve.controller --host 0.0.0.0 --port 10000\n",
    "```\n",
    "\n",
    "\n",
    "Then, in another terminal, start the worker, which will load the model to the GPU:\n",
    "```bash\n",
    "python -m llava.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 --port 40000 --worker http://localhost:40000 --model-path liuhaotian/llava-v1.5-13b\n",
    "``"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "93bf7915",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run this code block only if you want to run LlaVA locally\n",
    "if LLAVA_MODE == \"local\":\n",
    "    llava_config_list = [\n",
    "        {\n",
    "            \"model\": \"llava-v1.5-13b\",\n",
    "            \"api_key\": \"None\",\n",
    "            \"base_url\": \"http://0.0.0.0:10000\",\n",
    "        }\n",
    "    ]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "307852dd",
   "metadata": {},
   "source": [
    "# Multimodal Functions\n",
    "\n",
    "We cal test the `llava_call` function with the following AutoGen image.\n",
    "![](https://raw.githubusercontent.com/microsoft/autogen/main/website/static/img/autogen_agentchat.png)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7c1be77f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The AutoGen framework is a tool for creating and managing conversational agents. It allows for the creation of multiple-agent conversations, enabling complex interactions between different agents. The framework is designed to be flexible and scalable, allowing for the addition of new agents and conversations as needed.\n",
      "\n",
      "The framework consists of three main components:\n",
      "\n",
      "1. Agents: These are the individual conversational entities that can be created and managed within the framework. Each agent has its own unique set of conversational capabilities and can engage in conversations with other agents.\n",
      "\n",
      "2. Conversations: These are the interactions between agents, which can be managed and directed by the framework. Conversations can be structured and organized to facilitate efficient communication between agents.\n",
      "\n",
      "3. Flexibility: The framework is designed to be flexible, allowing for the addition of new agents and conversations as needed. This flexibility enables the framework to adapt to changing requirements and facilitate the development of more complex conversational systems.\n"
     ]
    }
   ],
   "source": [
    "rst = llava_call(\n",
    "    \"Describe this AutoGen framework <img https://raw.githubusercontent.com/microsoft/autogen/main/website/static/img/autogen_agentchat.png> with bullet points.\",\n",
    "    llm_config={\"config_list\": llava_config_list, \"temperature\": 0},\n",
    ")\n",
    "\n",
    "print(rst)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e4faf59",
   "metadata": {},
   "source": [
    "<a id=\"app-1\"></a>\n",
    "## Application 1: Image Chat\n",
    "\n",
    "In this section, we present a straightforward dual-agent architecture to enable user to chat with a multimodal agent.\n",
    "\n",
    "\n",
    "First, we show this image and ask a question.\n",
    "![](https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3d5580e",
   "metadata": {},
   "source": [
    "Within the user proxy agent, we can decide to activate the human input mode or not (for here, we use human_input_mode=\"NEVER\" for conciseness). This allows you to interact with LLaVA in a multi-round dialogue, enabling you to provide feedback as the conversation unfolds."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "67157629",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mUser_proxy\u001b[0m (to image-explainer):\n",
      "\n",
      "What's the breed of this dog? \n",
      "<image>.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> USING AUTO REPLY...\u001b[0m\n",
      "\u001b[34mYou are an AI agent and you can view images.\n",
      "###Human: What's the breed of this dog? \n",
      "<image>.\n",
      "\n",
      "###Assistant: \u001b[0m\n",
      "\u001b[33mimage-explainer\u001b[0m (to User_proxy):\n",
      "\n",
      "The breed of the dog in the image is a poodle.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "image_agent = LLaVAAgent(\n",
    "    name=\"image-explainer\",\n",
    "    max_consecutive_auto_reply=10,\n",
    "    llm_config={\"config_list\": llava_config_list, \"temperature\": 0.5, \"max_new_tokens\": 1000},\n",
    ")\n",
    "\n",
    "user_proxy = autogen.UserProxyAgent(\n",
    "    name=\"User_proxy\",\n",
    "    system_message=\"A human admin.\",\n",
    "    code_execution_config={\n",
    "        \"last_n_messages\": 3,\n",
    "        \"work_dir\": \"groupchat\",\n",
    "        \"use_docker\": False,\n",
    "    },  # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n",
    "    human_input_mode=\"NEVER\",  # Try between ALWAYS or NEVER\n",
    "    max_consecutive_auto_reply=0,\n",
    ")\n",
    "\n",
    "# Ask the question with an image\n",
    "user_proxy.initiate_chat(\n",
    "    image_agent,\n",
    "    message=\"\"\"What's the breed of this dog?\n",
    "<img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\"\"\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f60521d",
   "metadata": {},
   "source": [
    "Now, input another image, and ask a followup question.\n",
    "\n",
    "![](https://th.bing.com/th/id/OIP.29Mi2kJmcHHyQVGe_0NG7QHaEo?pid=ImgDet&rs=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "73a2b234",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mUser_proxy\u001b[0m (to image-explainer):\n",
      "\n",
      "What is this breed? \n",
      "<image>\n",
      "\n",
      "Among the breeds, which one barks less?\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> USING AUTO REPLY...\u001b[0m\n",
      "\u001b[34mYou are an AI agent and you can view images.\n",
      "###Human: What's the breed of this dog? \n",
      "<image>.\n",
      "###Assistant: The breed of the dog in the image is a poodle.\n",
      "###Human: What is this breed? \n",
      "<image>\n",
      "\n",
      "Among the breeds, which one barks less?\n",
      "\n",
      "###Assistant: \u001b[0m\n",
      "\u001b[33mimage-explainer\u001b[0m (to User_proxy):\n",
      "\n",
      "Among the breeds, poodles tend to bark less compared to other breeds. However, it is important to note that individual dogs may have different temperaments and barking habits, regardless of their breed.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# Ask the question with an image\n",
    "user_proxy.send(\n",
    "    message=\"\"\"What is this breed?\n",
    "<img https://th.bing.com/th/id/OIP.29Mi2kJmcHHyQVGe_0NG7QHaEo?pid=ImgDet&rs=1>\n",
    "\n",
    "Among the breeds, which one barks less?\"\"\",\n",
    "    recipient=image_agent,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c40d0eb",
   "metadata": {},
   "source": [
    "<a id=\"app-2\"></a>\n",
    "## Application 2: Figure Creator\n",
    "\n",
    "Here, we define a `FigureCreator` agent, which contains three child agents: commander, coder, and critics.\n",
    "\n",
    "- Commander: interacts with users, runs code, and coordinates the flow between the coder and critics.\n",
    "- Coder: writes code for visualization.\n",
    "- Critics: LLaVA-based agent that provides comments and feedback on the generated image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e8eca993",
   "metadata": {},
   "outputs": [],
   "source": [
    "class FigureCreator(AssistantAgent):\n",
    "    def __init__(self, n_iters=2, **kwargs):\n",
    "        \"\"\"\n",
    "        Initializes a FigureCreator instance.\n",
    "\n",
    "        This agent facilitates the creation of visualizations through a collaborative effort among its child agents: commander, coder, and critics.\n",
    "\n",
    "        Parameters:\n",
    "            - n_iters (int, optional): The number of \"improvement\" iterations to run. Defaults to 2.\n",
    "            - **kwargs: keyword arguments for the parent AssistantAgent.\n",
    "        \"\"\"\n",
    "        super().__init__(**kwargs)\n",
    "        self.register_reply([Agent, None], reply_func=FigureCreator._reply_user, position=0)\n",
    "        self._n_iters = n_iters\n",
    "\n",
    "    def _reply_user(self, messages=None, sender=None, config=None):\n",
    "        if all((messages is None, sender is None)):\n",
    "            error_msg = f\"Either {messages=} or {sender=} must be provided.\"\n",
    "            logger.error(error_msg)  # noqa: F821\n",
    "            raise AssertionError(error_msg)\n",
    "\n",
    "        if messages is None:\n",
    "            messages = self._oai_messages[sender]\n",
    "\n",
    "        user_question = messages[-1][\"content\"]\n",
    "\n",
    "        ### Define the agents\n",
    "        commander = AssistantAgent(\n",
    "            name=\"Commander\",\n",
    "            human_input_mode=\"NEVER\",\n",
    "            max_consecutive_auto_reply=10,\n",
    "            system_message=\"Help me run the code, and tell other agents it is in the <img result.jpg> file location.\",\n",
    "            is_termination_msg=lambda x: x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n",
    "            code_execution_config={\n",
    "                \"last_n_messages\": 3,\n",
    "                \"work_dir\": \".\",\n",
    "                \"use_docker\": False,\n",
    "            },  # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n",
    "            llm_config=self.llm_config,\n",
    "        )\n",
    "\n",
    "        critics = LLaVAAgent(\n",
    "            name=\"Critics\",\n",
    "            system_message=\"\"\"Criticize the input figure. How to replot the figure so it will be better? Find bugs and issues for the figure.\n",
    "            Pay attention to the color, format, and presentation. Keep in mind of the reader-friendliness.\n",
    "            If you think the figures is good enough, then simply say NO_ISSUES\"\"\",\n",
    "            llm_config={\"config_list\": llava_config_list},\n",
    "            human_input_mode=\"NEVER\",\n",
    "            max_consecutive_auto_reply=1,\n",
    "            #     use_docker=False,\n",
    "        )\n",
    "\n",
    "        coder = AssistantAgent(\n",
    "            name=\"Coder\",\n",
    "            llm_config=self.llm_config,\n",
    "        )\n",
    "\n",
    "        coder.update_system_message(\n",
    "            coder.system_message\n",
    "            + \"ALWAYS save the figure in `result.jpg` file. Tell other agents it is in the <img result.jpg> file location.\"\n",
    "        )\n",
    "\n",
    "        # Data flow begins\n",
    "        commander.initiate_chat(coder, message=user_question)\n",
    "        img = Image.open(\"result.jpg\")\n",
    "        plt.imshow(img)\n",
    "        plt.axis(\"off\")  # Hide the axes\n",
    "        plt.show()\n",
    "\n",
    "        for i in range(self._n_iters):\n",
    "            commander.send(message=\"Improve <img result.jpg>\", recipient=critics, request_reply=True)\n",
    "\n",
    "            feedback = commander._oai_messages[critics][-1][\"content\"]\n",
    "            if feedback.find(\"NO_ISSUES\") >= 0:\n",
    "                break\n",
    "            commander.send(\n",
    "                message=\"Here is the feedback to your figure. Please improve! Save the result to `result.jpg`\\n\"\n",
    "                + feedback,\n",
    "                recipient=coder,\n",
    "                request_reply=True,\n",
    "            )\n",
    "            img = Image.open(\"result.jpg\")\n",
    "            plt.imshow(img)\n",
    "            plt.axis(\"off\")  # Hide the axes\n",
    "            plt.show()\n",
    "\n",
    "        return True, \"result.jpg\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "977b9017",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mUser\u001b[0m (to Figure Creator~):\n",
      "\n",
      "\n",
      "Plot a figure by using the data from:\n",
      "https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\n",
      "\n",
      "I want to show both temperature high and low.\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCommander\u001b[0m (to Coder):\n",
      "\n",
      "\n",
      "Plot a figure by using the data from:\n",
      "https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\n",
      "\n",
      "I want to show both temperature high and low.\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "First, we will download the CSV file, then we will parse it using pandas, a popular data analysis library in Python. After that, we will plot the data using matplotlib.\n",
      "\n",
      "This is how we could do this:\n",
      "\n",
      "```python\n",
      "import pandas as pd\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "# Step 1: Load the Data\n",
      "url = \"https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\"\n",
      "data = pd.read_csv(url)\n",
      "\n",
      "# Step 2: Parse the date to datetime format\n",
      "data['date'] = pd.to_datetime(data['date'])\n",
      "\n",
      "# Step 3: Plot the Data\n",
      "plt.figure(figsize=(10,6))\n",
      "plt.plot(data['date'], data['temp_max'], label='Temp Max')\n",
      "plt.plot(data['date'], data['temp_min'], label='Temp Min')\n",
      "\n",
      "plt.title('Seattle Weather')\n",
      "plt.xlabel('Date')\n",
      "plt.ylabel('Temperature (F)')\n",
      "plt.legend()\n",
      "plt.grid()\n",
      "\n",
      "# Save the figure\n",
      "plt.savefig('result.jpg')\n",
      "\n",
      "# Display the plot\n",
      "plt.show()\n",
      "```\n",
      "\n",
      "When you run this code, it will load the data from the given URL, parse the 'date' column to datetime format, then plot the \"temp_max\" and \"temp_min\" over time. The resulting plot is then shown to you. The plot will automatically be saved as 'result.jpg' in the current directory. I will also submit these instructions to other agents.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n",
      "\u001b[33mCommander\u001b[0m (to Coder):\n",
      "\n",
      "exitcode: 0 (execution succeeded)\n",
      "Code output: \n",
      "Figure(1000x600)\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "Great! The code has successfully executed and the plot was generated and saved as `result.jpg`. \n",
      "\n",
      "If you check the working directory, you should find the figure saved as `result.jpg`.\n",
      "\n",
      "Let me know if you need help with anything else.\n",
      "\n",
      "TERMINATE\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 137416 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mCommander\u001b[0m (to Critics):\n",
      "\n",
      "Improve <image>\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[34mCriticize the input figure. How to replot the figure so it will be better? Find bugs and issues for the figure. \n",
      "            Pay attention to the color, format, and presentation. Keep in mind of the reader-friendliness.\n",
      "            If you think the figures is good enough, then simply say NO_ISSUES\n",
      "###Human: Improve <image>\n",
      "\n",
      "###Assistant: \u001b[0m\n",
      "\u001b[33mCritics\u001b[0m (to Commander):\n",
      "\n",
      "The input figure shows a graph of Seattle weather, with a blue line representing the temperature and an orange line representing the humidity. The graph is displayed on a white background, with the title \"Seattle Weather\" at the top.\n",
      "\n",
      "There are a few issues with the figure that could be improved:\n",
      "\n",
      "1. The color scheme for the temperature and humidity lines is not clear. The blue line represents the temperature, but it is not immediately clear to the viewer. A more distinct color or labeling could help clarify this.\n",
      "2. The graph does not have any axis labels or units, making it difficult for the viewer to understand the scale and units of the temperature and humidity values.\n",
      "3. The graph is not well-organized, with the temperature and humidity lines overlapping and not clearly separated. A more organized layout could help the viewer better understand the relationship between the two variables.\n",
      "\n",
      "To improve the figure, the following changes could be made:\n",
      "\n",
      "1. Use a more distinct color for the temperature line, such as red, and label it with a clear title, such as \"Temperature (°C)\".\n",
      "2. Add axis labels for both the temperature and humidity lines, indicating the units and scale of the values.\n",
      "3. Separate the temperature and humidity lines, either by using different colors or by adding a clear separation between them.\n",
      "4. Consider adding a legend or key to help the viewer understand the meaning of the different colors and lines on the graph.\n",
      "\n",
      "By making these changes, the figure will be more reader-friendly and easier to understand.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCommander\u001b[0m (to Coder):\n",
      "\n",
      "Here is the feedback to your figure. Please improve! Save the result to `result.jpg`\n",
      "The input figure shows a graph of Seattle weather, with a blue line representing the temperature and an orange line representing the humidity. The graph is displayed on a white background, with the title \"Seattle Weather\" at the top.\n",
      "\n",
      "There are a few issues with the figure that could be improved:\n",
      "\n",
      "1. The color scheme for the temperature and humidity lines is not clear. The blue line represents the temperature, but it is not immediately clear to the viewer. A more distinct color or labeling could help clarify this.\n",
      "2. The graph does not have any axis labels or units, making it difficult for the viewer to understand the scale and units of the temperature and humidity values.\n",
      "3. The graph is not well-organized, with the temperature and humidity lines overlapping and not clearly separated. A more organized layout could help the viewer better understand the relationship between the two variables.\n",
      "\n",
      "To improve the figure, the following changes could be made:\n",
      "\n",
      "1. Use a more distinct color for the temperature line, such as red, and label it with a clear title, such as \"Temperature (°C)\".\n",
      "2. Add axis labels for both the temperature and humidity lines, indicating the units and scale of the values.\n",
      "3. Separate the temperature and humidity lines, either by using different colors or by adding a clear separation between them.\n",
      "4. Consider adding a legend or key to help the viewer understand the meaning of the different colors and lines on the graph.\n",
      "\n",
      "By making these changes, the figure will be more reader-friendly and easier to understand.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "Thank you for your feedback. I will indeed make the improvements accordingly. This time, each graph line will be labeled showing which indicates \"Temp Max\" and which indicates \"Temp Min\". I will also assign a red color to the line representing \"Temp Max\" and a blue color to the line representing \"Temp Min\". I will make sure the axes have the appropriate labels. \n",
      "\n",
      "Follow this code and it will improve your figure and saved as `result.jpg`:\n",
      "\n",
      "```python\n",
      "import pandas as pd\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "# Step 1: Load the Data\n",
      "url = \"https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\"\n",
      "data = pd.read_csv(url)\n",
      "\n",
      "# Step 2: Parse the date to datetime format\n",
      "data['date'] = pd.to_datetime(data['date'])\n",
      "\n",
      "# Step 3: Plot the Data\n",
      "plt.figure(figsize=(10,6))\n",
      "plt.plot(data['date'], data['temp_max'], color='red', label='Temp Max')\n",
      "plt.plot(data['date'], data['temp_min'], color='blue', label='Temp Min')\n",
      "\n",
      "plt.title('Seattle Weather')\n",
      "plt.xlabel('Date')\n",
      "plt.ylabel('Temperature (F)')\n",
      "plt.legend()\n",
      "plt.grid()\n",
      "\n",
      "# Save the figure\n",
      "plt.savefig('result.jpg')\n",
      "\n",
      "# Display the plot\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "This code improves upon the previous one by adding distinct colors for the temperature max and min lines (red and blue, respectively), labeling each line, and providing proper axes labels. The result will be a plot that is more reader-friendly and easier to understand. The plot will automatically be saved as 'result.jpg' in the current directory. I will also submit these instructions to other agents.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n",
      "\u001b[33mCommander\u001b[0m (to Coder):\n",
      "\n",
      "exitcode: 0 (execution succeeded)\n",
      "Code output: \n",
      "Figure(1000x600)\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "Great, the code has been successfully executed and the updates have been made based on the feedback. \n",
      "\n",
      "You should now have a more reader-friendly plot, with clear distinction between maximum and minimum temperatures, and more evident axis labels. This updated figure is saved as `result.jpg` in your current directory.\n",
      "\n",
      "If you need further improvements or need assistance with something else, feel free to ask.\n",
      "\n",
      "TERMINATE\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 144436 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mCommander\u001b[0m (to Critics):\n",
      "\n",
      "Improve <image>\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCommander\u001b[0m (to Coder):\n",
      "\n",
      "Here is the feedback to your figure. Please improve! Save the result to `result.jpg`\n",
      "Improve <img result.jpg>\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "I apologize for the misunderstanding, but without more specific feedback about the figure, it's difficult to understand what improvements are needed. As of now, the figure includes distinct colors for max and min temperatures, clear labeling of lines, and proper axis labels.\n",
      "\n",
      "However, if you want to improve visual clarity, you can try:\n",
      "\n",
      "- Changing the line style (making one of them dotted, for instance).\n",
      "- Adding a title to the legend for better clarification.\n",
      "- Changing the figure size for a improved view.\n",
      "\n",
      "Here is the modified code:\n",
      "\n",
      "```python\n",
      "import pandas as pd\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "# Step 1: Load the Data\n",
      "url = \"https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\"\n",
      "data = pd.read_csv(url)\n",
      "\n",
      "# Step 2: Parse the date to datetime format\n",
      "data['date'] = pd.to_datetime(data['date'])\n",
      "\n",
      "# Step 3: Plot the Data\n",
      "plt.figure(figsize=(12,8))\n",
      "plt.plot(data['date'], data['temp_max'], 'r-', label='Temp Max')\n",
      "plt.plot(data['date'], data['temp_min'], 'b--', label='Temp Min')\n",
      "\n",
      "plt.title('Seattle Weather')\n",
      "plt.xlabel('Date')\n",
      "plt.ylabel('Temperature (F)')\n",
      "plt.legend(title='Temperature')\n",
      "\n",
      "plt.grid()\n",
      "\n",
      "# Save the figure\n",
      "plt.savefig('result.jpg')\n",
      "\n",
      "# Display the plot\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "This code changes the line style for the min temperature to dots for better distinction. Adjusts the figure size for a better representation and adds a title to the legend. The plot will automatically be saved as 'result.jpg' in the current directory. You are encouraged to run this code and I will also submit these instructions to other agents.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n",
      "\u001b[33mCommander\u001b[0m (to Coder):\n",
      "\n",
      "exitcode: 0 (execution succeeded)\n",
      "Code output: \n",
      "Figure(1200x800)\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "Great! The code has successfully executed and the plot was generated and saved as `result.jpg`. The figure now includes distinct colors for max and min temperatures, different line styles, and a clearer legend.\n",
      "\n",
      "You will find the figure saved as 'result.jpg' in your current directory.\n",
      "\n",
      "If you need any further improvements or other assistance, please let me know.\n",
      "\n",
      "TERMINATE\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 155096 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mFigure Creator~\u001b[0m (to User):\n",
      "\n",
      "result.jpg\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "config_list_gpt4 = autogen.config_list_from_json(\n",
    "    \"OAI_CONFIG_LIST\",\n",
    "    filter_dict={\n",
    "        \"model\": [\"gpt-4\", \"gpt-4-0314\", \"gpt4\", \"gpt-4-32k\", \"gpt-4-32k-0314\", \"gpt-4-32k-v0314\"],\n",
    "    },\n",
    ")\n",
    "\n",
    "gpt4_llm_config = {\"config_list\": config_list_gpt4, \"cache_seed\": 42}\n",
    "\n",
    "# config_list_gpt35 = autogen.config_list_from_json(\n",
    "#     \"OAI_CONFIG_LIST\",\n",
    "#     filter_dict={\n",
    "#         \"model\": [\"gpt-35-turbo\", \"gpt-3.5-turbo\"],\n",
    "#     },\n",
    "# )\n",
    "\n",
    "# gpt35_llm_config = {\"config_list\": config_list_gpt35, \"cache_seed\": 42}\n",
    "\n",
    "\n",
    "creator = FigureCreator(name=\"Figure Creator~\", llm_config=gpt4_llm_config)\n",
    "\n",
    "user_proxy = autogen.UserProxyAgent(\n",
    "    name=\"User\", human_input_mode=\"NEVER\", max_consecutive_auto_reply=0, code_execution_config={\"use_docker\": False}\n",
    ")  # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n",
    "\n",
    "user_proxy.initiate_chat(\n",
    "    creator,\n",
    "    message=\"\"\"\n",
    "Plot a figure by using the data from:\n",
    "https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\n",
    "\n",
    "I want to show both temperature high and low.\n",
    "\"\"\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "f0a58827",
   "metadata": {},
   "outputs": [],
   "source": [
    "if os.path.exists(\"result.jpg\"):\n",
    "    os.remove(\"result.jpg\")  # clean up"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
