{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2c75da30",
   "metadata": {},
   "source": [
    "# Engaging with Multimodal Models: GPT-4V in AutoGen\n",
    "\n",
    "In AutoGen, leveraging multimodal models can be done through two different methodologies:\n",
    "1. **MultimodalAgent**: Supported by GPT-4V and other LMMs, this agent is endowed with visual cognitive abilities, allowing it to engage in interactions comparable to those of other ConversableAgents.\n",
    "2. **VisionCapability**: For LLM-based agents lacking inherent visual comprehension, we introduce vision capabilities by converting images into descriptive captions.\n",
    "\n",
    "This guide will delve into each approach, providing insights into their application and integration."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f51914c",
   "metadata": {},
   "source": [
    "### Before everything starts, install AutoGen with the `lmm` option\n",
    "\n",
    "Install `autogen-agentchat`:\n",
    "```bash\n",
    "pip install \"autogen-agentchat[lmm]~=0.2\"\n",
    "```\n",
    "\n",
    "For more information, please refer to the [installation guide](/docs/installation/).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "67d45964",
   "metadata": {},
   "outputs": [],
   "source": [
    "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 numpy as np\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.capabilities.vision_capability import VisionCapability\n",
    "from autogen.agentchat.contrib.img_utils import get_pil_image, pil_to_data_uri\n",
    "from autogen.agentchat.contrib.multimodal_conversable_agent import MultimodalConversableAgent\n",
    "from autogen.code_utils import content_str"
   ]
  },
  {
   "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 LMM in a multi-round dialogue, enabling you to provide feedback as the conversation unfolds."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b1db6f5d",
   "metadata": {},
   "outputs": [],
   "source": [
    "config_list_4v = autogen.config_list_from_json(\n",
    "    \"OAI_CONFIG_LIST\",\n",
    "    filter_dict={\n",
    "        \"model\": [\"gpt-4-vision-preview\"],\n",
    "    },\n",
    ")\n",
    "\n",
    "\n",
    "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}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9c628db",
   "metadata": {},
   "source": [
    "Learn more about configuring LLMs for agents [here](/docs/topics/llm_configuration)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "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[33mimage-explainer\u001b[0m (to User_proxy):\n",
      "\n",
      "The dog in the image appears to be a Goldendoodle, which is a crossbreed between a Golden Retriever and a Poodle. They are known for their curly, hypoallergenic coats, which can vary in color, and their friendly and affectionate nature.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/beibinli/autogen/autogen/agentchat/conversable_agent.py:1121: UserWarning: Cannot extract summary using last_msg: 'list' object has no attribute 'replace'. Using an empty str as summary.\n",
      "  warnings.warn(f\"Cannot extract summary using last_msg: {e}. Using an empty str as summary.\", UserWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "ChatResult(chat_id=None, chat_history=[{'content': \"What's the breed of this dog?\\n<img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\", 'role': 'assistant'}, {'content': 'The dog in the image appears to be a Goldendoodle, which is a crossbreed between a Golden Retriever and a Poodle. They are known for their curly, hypoallergenic coats, which can vary in color, and their friendly and affectionate nature.', 'role': 'user'}], summary='', cost=({'total_cost': 0.013030000000000002, 'gpt-4-1106-vision-preview': {'cost': 0.013030000000000002, 'prompt_tokens': 1132, 'completion_tokens': 57, 'total_tokens': 1189}}, {'total_cost': 0}), human_input=[])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "image_agent = MultimodalConversableAgent(\n",
    "    name=\"image-explainer\",\n",
    "    max_consecutive_auto_reply=10,\n",
    "    llm_config={\"config_list\": config_list_4v, \"temperature\": 0.5, \"max_tokens\": 300},\n",
    ")\n",
    "\n",
    "user_proxy = autogen.UserProxyAgent(\n",
    "    name=\"User_proxy\",\n",
    "    system_message=\"A human admin.\",\n",
    "    human_input_mode=\"NEVER\",  # Try between ALWAYS or NEVER\n",
    "    max_consecutive_auto_reply=0,\n",
    "    code_execution_config={\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",
    ")\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": 4,
   "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[33mimage-explainer\u001b[0m (to User_proxy):\n",
      "\n",
      "The dog in the image is a Siberian Husky. They are known for their striking appearance, with thick fur, erect triangular ears, and distinctive markings.\n",
      "\n",
      "When comparing the barking tendencies of Siberian Huskies and Goldendoodles, Huskies are generally known to bark less. Siberian Huskies are more prone to howling and vocalizing in other ways rather than barking. Goldendoodles can vary in their tendency to bark based on the traits they inherit from their Golden Retriever and Poodle parents. However, every dog is an individual, and their environment, training, and socialization can greatly influence their tendency to bark.\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: LMM-based agent that provides comments and feedback on the generated image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "1e057758",
   "metadata": {},
   "outputs": [],
   "source": [
    "working_dir = \"tmp/\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e8eca993",
   "metadata": {},
   "outputs": [],
   "source": [
    "class FigureCreator(ConversableAgent):\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",
    "        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={\"last_n_messages\": 3, \"work_dir\": working_dir, \"use_docker\": False},\n",
    "            llm_config=self.llm_config,\n",
    "        )\n",
    "\n",
    "        critics = MultimodalConversableAgent(\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\": config_list_4v, \"max_tokens\": 300},\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(os.path.join(working_dir, \"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(\n",
    "                message=f\"Improve <img {os.path.join(working_dir, 'result.jpg')}>\",\n",
    "                recipient=critics,\n",
    "                request_reply=True,\n",
    "            )\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(os.path.join(working_dir, \"result.jpg\"))\n",
    "            plt.imshow(img)\n",
    "            plt.axis(\"off\")  # Hide the axes\n",
    "            plt.show()\n",
    "\n",
    "        return True, os.path.join(working_dir, \"result.jpg\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "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",
      "Sure, let's first download the CSV data from the provided URL using Python and then we'll plot the figure with both temperature high and low.\n",
      "\n",
      "To start with, I'll provide you with a Python script that will download the CSV file and then plot the temperatures highs and lows.\n",
      "\n",
      "Please run this Python code:\n",
      "\n",
      "```python\n",
      "# filename: plot_temperatures.py\n",
      "import pandas as pd\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "# URL to download the CSV data\n",
      "url = \"https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\"\n",
      "\n",
      "# Download the data\n",
      "data = pd.read_csv(url)\n",
      "\n",
      "# Now, let us plot the high and low temperatures\n",
      "plt.figure(figsize=(10, 5))\n",
      "plt.plot(data['date'], data['temp_max'], label='High Temp')\n",
      "plt.plot(data['date'], data['temp_min'], label='Low Temp')\n",
      "\n",
      "# Providing labels and title\n",
      "plt.xlabel('Date')\n",
      "plt.ylabel('Temperature (°C)')\n",
      "plt.title('High and Low Temperatures in Seattle')\n",
      "plt.legend()\n",
      "\n",
      "# Rotate the dates on x-axis for better readability\n",
      "plt.xticks(rotation=45)\n",
      "plt.tight_layout()\n",
      "\n",
      "# Save the figure\n",
      "plt.savefig('result.jpg')\n",
      "\n",
      "print(\"The plot has been saved as 'result.jpg'.\")\n",
      "```\n",
      "\n",
      "Make sure you have the required packages (`pandas` and `matplotlib`) installed. If they are not installed, you can install them using `pip`:\n",
      "\n",
      "```sh\n",
      "pip install pandas matplotlib\n",
      "```\n",
      "\n",
      "After running the script, you should see a message indicating that the plot has been saved as 'result.jpg'.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n",
      "\u001b[31m\n",
      ">>>>>>>> EXECUTING CODE BLOCK 1 (inferred language is sh)...\u001b[0m\n",
      "\u001b[33mCommander\u001b[0m (to Coder):\n",
      "\n",
      "exitcode: 0 (execution succeeded)\n",
      "Code output: \n",
      "The plot has been saved as 'result.jpg'.\n",
      "\n",
      "Requirement already satisfied: pandas in /home/beibinli/anaconda3/lib/python3.9/site-packages (1.5.3)\n",
      "Requirement already satisfied: matplotlib in /home/beibinli/anaconda3/lib/python3.9/site-packages (3.7.1)\n",
      "Requirement already satisfied: python-dateutil>=2.8.1 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from pandas) (2.8.2)\n",
      "Requirement already satisfied: pytz>=2020.1 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from pandas) (2022.7.1)\n",
      "Requirement already satisfied: numpy>=1.20.3 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from pandas) (1.23.5)\n",
      "Requirement already satisfied: contourpy>=1.0.1 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (1.0.5)\n",
      "Requirement already satisfied: cycler>=0.10 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (0.11.0)\n",
      "Requirement already satisfied: fonttools>=4.22.0 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (4.25.0)\n",
      "Requirement already satisfied: kiwisolver>=1.0.1 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (1.4.4)\n",
      "Requirement already satisfied: packaging>=20.0 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (23.2)\n",
      "Requirement already satisfied: pillow>=6.2.0 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (10.1.0)\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (3.0.9)\n",
      "Requirement already satisfied: importlib-resources>=3.2.0 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from matplotlib) (5.13.0)\n",
      "Requirement already satisfied: zipp>=3.1.0 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from importlib-resources>=3.2.0->matplotlib) (3.11.0)\n",
      "Requirement already satisfied: six>=1.5 in /home/beibinli/anaconda3/lib/python3.9/site-packages (from python-dateutil>=2.8.1->pandas) (1.16.0)\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "The Python script executed successfully, and the plot has been saved as 'result.jpg'. You should now be able to find the figure file at the mentioned location. \n",
      "\n",
      "The necessary packages were already installed in your environment, as indicated by your output, so no further action was required there.\n",
      "\n",
      "The figure shows the high and low temperatures for Seattle as indicated by the data in the CSV file you provided. If you have any other requests or need further assistance, feel free to ask. If not, and if you are satisfied with the result, we can conclude this task.\n",
      "\n",
      "TERMINATE\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 130936 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[33mCritics\u001b[0m (to Commander):\n",
      "\n",
      "The plot depicting high and low temperatures in Seattle can be improved in several ways:\n",
      "\n",
      "1. Date Axis: The dates on the x-axis are not visible or readable, which makes it hard to associate the temperature data with specific time periods. Consider formatting the date axis so that the dates are displayed at a readable angle or with sufficient spacing.\n",
      "\n",
      "2. X-axis Labeling: There appears to be an issue with the x-axis labels or ticks as it shows a dense black area, indicating overlapping or condensed labels. The frequency and format of the labels should be adjusted to prevent overlap and allow for clear reading.\n",
      "\n",
      "3. Y-axis Range: Consider starting the y-axis at a lower value if the temperature data permits, to give more space to the temperature lines and improve readability.\n",
      "\n",
      "4. Gridlines: Adding horizontal gridlines can aid in reading specific temperatures at a glance.\n",
      "\n",
      "5. Legend: The legend clearly indicates which color corresponds to high and low temperatures, which is good. Ensure the legend does not obscure any important data.\n",
      "\n",
      "6. Resolution: The actual resolution of the image may be fine, but the x-axis issue might give the illusion of a low-resolution image. Once the x-axis is corrected, the overall clarity of the chart may naturally improve.\n",
      "\n",
      "7. Color Contrast: The blue and orange color choices are generally good for contrast, but ensure they are differentiable to all users, including those who may be colorblind. Consider using colorblind-friendly palettes.\n",
      "\n",
      "8. Title: The title \"High\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 plot depicting high and low temperatures in Seattle can be improved in several ways:\n",
      "\n",
      "1. Date Axis: The dates on the x-axis are not visible or readable, which makes it hard to associate the temperature data with specific time periods. Consider formatting the date axis so that the dates are displayed at a readable angle or with sufficient spacing.\n",
      "\n",
      "2. X-axis Labeling: There appears to be an issue with the x-axis labels or ticks as it shows a dense black area, indicating overlapping or condensed labels. The frequency and format of the labels should be adjusted to prevent overlap and allow for clear reading.\n",
      "\n",
      "3. Y-axis Range: Consider starting the y-axis at a lower value if the temperature data permits, to give more space to the temperature lines and improve readability.\n",
      "\n",
      "4. Gridlines: Adding horizontal gridlines can aid in reading specific temperatures at a glance.\n",
      "\n",
      "5. Legend: The legend clearly indicates which color corresponds to high and low temperatures, which is good. Ensure the legend does not obscure any important data.\n",
      "\n",
      "6. Resolution: The actual resolution of the image may be fine, but the x-axis issue might give the illusion of a low-resolution image. Once the x-axis is corrected, the overall clarity of the chart may naturally improve.\n",
      "\n",
      "7. Color Contrast: The blue and orange color choices are generally good for contrast, but ensure they are differentiable to all users, including those who may be colorblind. Consider using colorblind-friendly palettes.\n",
      "\n",
      "8. Title: The title \"High\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "To address the feedback received on the figure, we'll make the following improvements to the plot:\n",
      "\n",
      "1. Format the date axis for better readability.\n",
      "2. Adjust the frequency and format of the x-axis labels to prevent overlap.\n",
      "3. Extend the y-axis range if possible.\n",
      "4. Add horizontal gridlines for ease of reading temperatures.\n",
      "5. Ensure the legend is placed properly to avoid obscuring data.\n",
      "6. Check for clarity once x-axis labels are resolved.\n",
      "7. Use a colorblind-friendly palette for the plot.\n",
      "8. Ensure the title is descriptive and relevant.\n",
      "\n",
      "Here's an updated Python script to make these improvements:\n",
      "\n",
      "```python\n",
      "# filename: improved_plot_temperatures.py\n",
      "import pandas as pd\n",
      "import matplotlib.pyplot as plt\n",
      "import matplotlib.dates as mdates\n",
      "\n",
      "# URL to download the CSV data\n",
      "url = \"https://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\"\n",
      "\n",
      "# Download the data\n",
      "data = pd.read_csv(url)\n",
      "data['date'] = pd.to_datetime(data['date'])\n",
      "\n",
      "# Now, let us plot the high and low temperatures\n",
      "plt.figure(figsize=(10, 5))\n",
      "plt.plot(data['date'], data['temp_max'], label='High Temp', color='tab:blue')\n",
      "plt.plot(data['date'], data['temp_min'], label='Low Temp', color='tab:orange')\n",
      "\n",
      "# Set the x-axis major locator and formatter for better date display\n",
      "plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator())\n",
      "plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))\n",
      "\n",
      "# Rotate the dates on x-axis for better readability\n",
      "plt.gcf().autofmt_xdate()\n",
      "\n",
      "# Improving Y-axis Range\n",
      "temp_min = data['temp_min'].min() - 5  # Give some padding below the min temp\n",
      "temp_max = data['temp_max'].max() + 5  # Give some padding above the max temp\n",
      "plt.ylim(temp_min, temp_max)\n",
      "\n",
      "# Adding gridlines and formatting the grid\n",
      "plt.grid(True, which='both', linestyle='--', linewidth=0.5)\n",
      "\n",
      "# Providing labels and title\n",
      "plt.xlabel('Date')\n",
      "plt.ylabel('Temperature (°C)')\n",
      "plt.title('High and Low Temperatures in Seattle Over Time')\n",
      "\n",
      "# Adjusting legend position\n",
      "plt.legend(loc='upper right')\n",
      "\n",
      "# Check done, no need to adjust color contrast as colorblind-friendly colors are used\n",
      "\n",
      "# Save the figure in high resolution\n",
      "plt.savefig('result.jpg', dpi=300)\n",
      "\n",
      "print(\"The improved plot has been saved as 'result.jpg'.\")\n",
      "```\n",
      "\n",
      "Please execute this script. Make sure that the `matplotlib.dates` module is available in your environment before running the script. If you encounter any issues, let me know.\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",
      "The improved plot has been saved as 'result.jpg'.\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "The improved plot has been saved successfully as 'result.jpg'. The improvements should address the feedback points provided earlier, resulting in a clearer and more readable figure.\n",
      "\n",
      "The dates on the x-axis are now formatted for better visibility, the frequency of x-axis labels has been adjusted, the y-axis range has been extended, gridlines have been added, and the legend has been positioned properly. The colors used should be distinguishable by individuals with color vision deficiencies.\n",
      "\n",
      "If no further improvements are needed, the task is now complete.\n",
      "\n",
      "TERMINATE\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 100860 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 tmp/result.jpg>\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mCoder\u001b[0m (to Commander):\n",
      "\n",
      "I apologize for any confusion, but as an AI, I don't have the capability to directly view the images generated. However, I can certainly help you further refine the plot based on standard practices if there is anything specific that you feel needs further adjustment.\n",
      "\n",
      "You mentioned feedback for a figure referenced as \"<img tmp/result.jpg>\". Since I can't view images, I'm assuming this feedback is a placeholder. In case there are specific changes or additional improvements you want to implement in the figure, please provide me with those details explicitly.\n",
      "\n",
      "For instance:\n",
      "- Are there any specific elements in the legend that still need repositioning?\n",
      "- Should the date formatting be adjusted further for better clarity?\n",
      "- Are there any other specific elements (e.g. colors, lines, labels, title) that require modification?\n",
      "\n",
      "Without specific feedback, I can suggest some general improvements, such as:\n",
      "\n",
      "- Ensuring the plot does not appear cluttered.\n",
      "- Checking if the aspect ratio is appropriate for the data being presented.\n",
      "- Verifying that the font sizes are readable.\n",
      "\n",
      "If specific feedback can be provided, we can proceed accordingly. Otherwise, please let me know if we should conclude the task.\n",
      "\n",
      "TERMINATE\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 100860 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",
      "tmp/result.jpg\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "ChatResult(chat_id=None, chat_history=[{'content': '\\nPlot a figure by using the data from:\\nhttps://raw.githubusercontent.com/vega/vega/main/docs/data/seattle-weather.csv\\n\\nI want to show both temperature high and low.\\n', 'role': 'assistant'}, {'content': 'tmp/result.jpg', 'role': 'user'}], summary='tmp/result.jpg', cost=({'total_cost': 0}, {'total_cost': 0}), human_input=[])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "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",
    ")\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": "markdown",
   "id": "a95d87c2",
   "metadata": {},
   "source": [
    "## Vision Capability: Group Chat Example with Multimodal Agent\n",
    "\n",
    "We recommend using VisionCapability for group chat managers so that it can organize and understand images better."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "56bd5742",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mUser_proxy\u001b[0m (to chat_manager):\n",
      "\n",
      "Write a poet for my image:\n",
      "                        <img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> USING AUTO REPLY...\u001b[0m\n",
      "\u001b[33mimage-explainer-1\u001b[0m (to chat_manager):\n",
      "\n",
      "In a cozy nook by the door, where whispers of adventure pour,\n",
      "Lies a curly apricot dream, with eyes that softly gleam.\n",
      "Westphal, a name upon his tag, a dapper bow, no room to brag.\n",
      "\n",
      "A poodle or a mix so sweet, with paws that barely seem to meet\n",
      "The floor that holds his tender frame, in this quiet household game.\n",
      "A sentinel of love and joy, more charming than any toy.\n",
      "\n",
      "His gaze, a tale of gentle days, and love that in his heart blazes.\n",
      "With boots behind, like silent guards, he watches without regards\n",
      "To the world's rush and its tides, in his serene abode, he abides.\n",
      "\n",
      "Oh, little guardian of the hearth, your worth is not defined by birth.\n",
      "But by the joy you bring to life, a respite from our daily strife.\n",
      "In you, we find a friend so true, Westphal, a treasure through and through.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> USING AUTO REPLY...\u001b[0m\n",
      "\u001b[33mimage-explainer-2\u001b[0m (to chat_manager):\n",
      "\n",
      "A pup so young with fur of gold,\n",
      "In a house where stories unfold.\n",
      "Westphal, with your bow so neat,\n",
      "Your puppy eyes, oh so sweet.\n",
      "\n",
      "Curled up on the floor so light,\n",
      "Your coat a soft, delightful sight.\n",
      "A mix, perhaps, of breeds so kind,\n",
      "In your face, pure joy we find.\n",
      "\n",
      "With a tag that jingles slight,\n",
      "And a bow tie oh so bright,\n",
      "You lie there with such grace,\n",
      "A calm presence in this place.\n",
      "\n",
      "Behind you, boots await the rain,\n",
      "But inside, you contently remain.\n",
      "A symbol of love, a furry delight,\n",
      "A beacon of warmth, shining so bright.\n",
      "\n",
      "In a world that's fast and vast,\n",
      "Your gentle spirit holds us fast.\n",
      "Westphal, with your charm so grand,\n",
      "You bring peace to this human land.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> USING AUTO REPLY...\u001b[0m\n",
      "\u001b[33mUser_proxy\u001b[0m (to chat_manager):\n",
      "\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[31m\n",
      ">>>>>>>> USING AUTO REPLY...\u001b[0m\n",
      "\u001b[33mUser_proxy\u001b[0m (to chat_manager):\n",
      "\n",
      "\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "agent1 = MultimodalConversableAgent(\n",
    "    name=\"image-explainer-1\",\n",
    "    max_consecutive_auto_reply=10,\n",
    "    llm_config={\"config_list\": config_list_4v, \"temperature\": 0.5, \"max_tokens\": 300},\n",
    "    system_message=\"Your image description is poetic and engaging.\",\n",
    ")\n",
    "agent2 = MultimodalConversableAgent(\n",
    "    name=\"image-explainer-2\",\n",
    "    max_consecutive_auto_reply=10,\n",
    "    llm_config={\"config_list\": config_list_4v, \"temperature\": 0.5, \"max_tokens\": 300},\n",
    "    system_message=\"Your image description is factual and to the point.\",\n",
    ")\n",
    "\n",
    "user_proxy = autogen.UserProxyAgent(\n",
    "    name=\"User_proxy\",\n",
    "    system_message=\"Desribe image for me.\",\n",
    "    human_input_mode=\"TERMINATE\",  # Try between ALWAYS, NEVER, and TERMINATE\n",
    "    max_consecutive_auto_reply=10,\n",
    "    code_execution_config={\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",
    ")\n",
    "\n",
    "# We set max_round to 5\n",
    "groupchat = autogen.GroupChat(agents=[agent1, agent2, user_proxy], messages=[], max_round=5)\n",
    "\n",
    "vision_capability = VisionCapability(lmm_config={\"config_list\": config_list_4v, \"temperature\": 0.5, \"max_tokens\": 300})\n",
    "group_chat_manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=gpt4_llm_config)\n",
    "vision_capability.add_to_agent(group_chat_manager)\n",
    "\n",
    "rst = user_proxy.initiate_chat(\n",
    "    group_chat_manager,\n",
    "    message=\"\"\"Write a poet for my image:\n",
    "                        <img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\"\"\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d69b6c81",
   "metadata": {},
   "source": [
    "## Behavior with and without VisionCapability for Agents\n",
    "\n",
    "\n",
    "Here, we show the behavior of an agent with and without VisionCapability. We use the same image and question as in the previous example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "aae1167f",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_no_vision = AssistantAgent(name=\"Regular LLM Agent\", llm_config=gpt4_llm_config)\n",
    "\n",
    "agent_with_vision = AssistantAgent(name=\"Regular LLM Agent with Vision Capability\", llm_config=gpt4_llm_config)\n",
    "vision_capability = VisionCapability(lmm_config={\"config_list\": config_list_4v, \"temperature\": 0.5, \"max_tokens\": 300})\n",
    "vision_capability.add_to_agent(agent_with_vision)\n",
    "\n",
    "\n",
    "user = UserProxyAgent(\n",
    "    name=\"User\",\n",
    "    human_input_mode=\"NEVER\",\n",
    "    max_consecutive_auto_reply=0,\n",
    "    code_execution_config={\"use_docker\": False},\n",
    ")\n",
    "\n",
    "message = \"\"\"Write a poet for my image:\n",
    "                        <img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "c9e81b7e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mUser\u001b[0m (to Regular LLM Agent):\n",
      "\n",
      "Write a poet for my image:\n",
      "                        <img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mRegular LLM Agent\u001b[0m (to User):\n",
      "\n",
      "As an AI, I can't directly view images or web content. However, I can help you generate a poem by gathering information about the image. Please describe the image for me, including details such as the setting, prominent colors, the mood it evokes, and any specific elements like animals, nature, cityscapes, or people that you want to be highlighted in the poem. Once you provide a description of the image, I can compose a poem based on that description.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "user.send(message=message, recipient=agent_no_vision, request_reply=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "8720820f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mUser\u001b[0m (to Regular LLM Agent with Vision Capability):\n",
      "\n",
      "Write a poet for my image:\n",
      "                        <img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "\u001b[33mRegular LLM Agent with Vision Capability\u001b[0m (to User):\n",
      "\n",
      "In apricot hues, a curl-coated pup reclines,\n",
      "With Westphal's name upon his tag that shines.\n",
      "A bow tie blooms in a brilliant blue sky,\n",
      "Amid a light-drenched floor where soft paws lie.\n",
      "\n",
      "Possessor of gazes, tender and deep,\n",
      "In the quiet foyer, his watch he keeps.\n",
      "Beneath black rubber guards of rainy days,\n",
      "He stirs a comfort, a homely embrace.\n",
      "\n",
      "His lineage drawn from the poodles' grace,\n",
      "Or maybe a mix, with a doodle's face,\n",
      "Gold or Lab, his curls are just as sweet,\n",
      "In each bouncing step, in each heartbeat.\n",
      "\n",
      "A picture of love, in a tiny frame,\n",
      "A heartbeat wrapped in an apricot mane.\n",
      "The pup in his calm, an invite to cheer,\n",
      "A whisper of joy in a pet-lover's ear.\n",
      "\n",
      "Around him, life's simple clutter does unfold,\n",
      "Yet untouched by worry, untouched by cold.\n",
      "With every breath, he claims this slice of earth,\n",
      "A master of mirth, from the moment of his birth.\n",
      "\n",
      "Paws outstretched on the soft, forgiving ground,\n",
      "His soulful eyes speak, without a sound.\n",
      "For in the sweet stillness of his gentle rest,\n",
      "Lies the simple truth that we are blessed.\n",
      "\n",
      "TERMINATE\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "user.send(message=message, recipient=agent_with_vision, request_reply=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba4d3753",
   "metadata": {},
   "source": [
    "## Custom Caption Function for Vision Capability\n",
    "\n",
    "In many use cases, we can use a custom function within the Vision Capability to transcribe an image into a caption.\n",
    "\n",
    "For instance, we can use rule-based algorithm or other models to detect the color, box, and other components inside the image.\n",
    "\n",
    "The custom model should take a path to the image and return a string caption.\n",
    "\n",
    "In the example below, the Vision Capability will call LMM to get caption and also call the custom function to get more information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "bff55c81",
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_description(image_url: str, image_data: Image = None, lmm_client: object = None) -> str:\n",
    "    \"\"\"\n",
    "    This function takes an image URL and returns the description.\n",
    "\n",
    "    Parameters:\n",
    "        - image_url (str): The URL of the image.\n",
    "        - image_data (PIL.Image): The image data.\n",
    "        - lmm_client (object): The LLM client object.\n",
    "\n",
    "    Returns:\n",
    "        - str: A description of the color of the image.\n",
    "    \"\"\"\n",
    "    # Print the arguments for illustration purpose\n",
    "    print(\"image_url\", image_url)\n",
    "    print(\"image_data\", image_data)\n",
    "    print(\"lmm_client\", lmm_client)\n",
    "\n",
    "    img_uri = pil_to_data_uri(image_data)  # cast data into URI (str) format for API call\n",
    "    lmm_out = lmm_client.create(\n",
    "        context=None,\n",
    "        messages=[\n",
    "            {\n",
    "                \"role\": \"user\",\n",
    "                \"content\": [\n",
    "                    {\"type\": \"text\", \"text\": \"Describe this image in 10 words.\"},\n",
    "                    {\n",
    "                        \"type\": \"image_url\",\n",
    "                        \"image_url\": {\n",
    "                            \"url\": img_uri,\n",
    "                        },\n",
    "                    },\n",
    "                ],\n",
    "            }\n",
    "        ],\n",
    "    )\n",
    "    description = lmm_out.choices[0].message.content\n",
    "    description = content_str(description)\n",
    "\n",
    "    # Convert the image into an array of pixels.\n",
    "    pixels = np.array(image_data)\n",
    "\n",
    "    # Calculate the average color.\n",
    "    avg_color_per_row = np.mean(pixels, axis=0)\n",
    "    avg_color = np.mean(avg_color_per_row, axis=0)\n",
    "    avg_color = avg_color.astype(int)  # Convert to integer for color values\n",
    "\n",
    "    # Format the average color as a string description.\n",
    "    caption = f\"\"\"The image is from {image_url}\n",
    "    It is about: {description}\n",
    "    The average color of the image is RGB:\n",
    "        ({avg_color[0]}, {avg_color[1]}, {avg_color[2]})\"\"\"\n",
    "\n",
    "    print(caption)  # For illustration purpose\n",
    "\n",
    "    return caption"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "cbafea62",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mUser\u001b[0m (to Regular LLM Agent with Custom Func and LMM):\n",
      "\n",
      "Write a poet for my image:\n",
      "                        <img https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0>.\n",
      "\n",
      "--------------------------------------------------------------------------------\n",
      "image_url https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0\n",
      "image_data <PIL.Image.Image image mode=RGB size=1920x1080 at 0x7F599DA4CCA0>\n",
      "lmm_client <autogen.oai.client.OpenAIWrapper object at 0x7f599da3ab20>\n",
      "The image is from https://th.bing.com/th/id/R.422068ce8af4e15b0634fe2540adea7a?rik=y4OcXBE%2fqutDOw&pid=ImgRaw&r=0\n",
      "    It is about: Cute brown curly-haired puppy with blue collar indoors.\n",
      "    The average color of the image is RGB: \n",
      "        (170, 155, 137)\n",
      "\u001b[33mRegular LLM Agent with Custom Func and LMM\u001b[0m (to User):\n",
      "\n",
      "Beneath a sky of homely hue,\n",
      "Where RGB blends a gentle stew,\n",
      "Lies a pup of curls and capers,\n",
      "Bound by blue, his neck in drapers.\n",
      "\n",
      "Soft in gaze, his eyes implore,\n",
      "Warming hearts down to the core,\n",
      "Coat of brown, with tangles sweet,\n",
      "Whispers of play in each petite feet.\n",
      "\n",
      "In a world quite vast and wide,\n",
      "Indoors he sits, with pride inside.\n",
      "A silent wish, a breath, a start,\n",
      "Curly companion, a work of art.\n",
      "\n",
      "Within the frame, he's captured still,\n",
      "Yet, through the lens, his charm does spill.\n",
      "A tiny heartbeat in the quiet room,\n",
      "His presence banishes all gloom.\n",
      "\n",
      "A puppy's joy, in sepia tone,\n",
      "With collar blue, he reigns alone.\n",
      "A picture's worth, this moment's glee,\n",
      "Cute curly friend, for all to see.\n",
      "\n",
      "This poem encapsulates the essence of the cute brown curly-haired puppy wearing a blue collar, blending an emotional portrayal with the aesthetic elements you provided.\n",
      "\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "agent_with_vision_and_func = AssistantAgent(\n",
    "    name=\"Regular LLM Agent with Custom Func and LMM\", llm_config=gpt4_llm_config\n",
    ")\n",
    "\n",
    "vision_capability_with_func = VisionCapability(\n",
    "    lmm_config={\"config_list\": config_list_4v, \"temperature\": 0.5, \"max_tokens\": 300},\n",
    "    custom_caption_func=my_description,\n",
    ")\n",
    "vision_capability_with_func.add_to_agent(agent_with_vision_and_func)\n",
    "\n",
    "user.send(message=message, recipient=agent_with_vision_and_func, request_reply=True)"
   ]
  }
 ],
 "metadata": {
  "front_matter": {
   "description": "In AutoGen, leveraging multimodal models can be done through two different methodologies: MultimodalConversableAgent and VisionCapability.",
   "tags": [
    "multimodal",
    "gpt-4v"
   ]
  },
  "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
}
