diff --git a/ICML2024/script.ipynb b/ICML2024/script.ipynb deleted file mode 100644 index da53b994..00000000 --- a/ICML2024/script.ipynb +++ /dev/null @@ -1,732 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 370, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " benchmark Task group max DOM k-tokens max Pruned DOM k-tokens \\\n", - "0 miniwob [ALL TASKS] 7.586 5.468 \n", - "1 miniwob [ALL TASKS] 9.978 6.304 \n", - "2 workarena form 1337.341 1255.558 \n", - "3 workarena knowledge 72.976 60.304 \n", - "4 workarena list-filter 1442.547 1373.995 \n", - "\n", - " max AXTree k-tokens episode DOM k-tokens episode Pruned DOM k-tokens \\\n", - "0 1.009 10.597492 4.143874 \n", - "1 2.196 11.799989 6.235014 \n", - "2 56.093 2838.753426 2293.452617 \n", - "3 6.229 316.468900 179.223000 \n", - "4 78.882 2226.093472 1648.841453 \n", - "\n", - " episode AXTree k-tokens agent \n", - "0 0.721944 base_agent \n", - "1 1.186288 full_agent \n", - "2 104.499426 base_agent \n", - "3 14.687900 base_agent \n", - "4 181.179585 base_agent \n" - ] - } - ], - "source": [ - "import pandas as pd\n", - "import numpy as np\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib.cm as cm\n", - "from matplotlib.colors import ListedColormap\n", - "\n", - "# Read the CSV file\n", - "df = pd.read_csv('data.csv')\n", - "\n", - "print(df.head())\n" - ] - }, - { - "cell_type": "code", - "execution_count": 371, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
benchmarkTask groupagenttypeobsvalue
0miniwobminiwob [ALL TASKS]base_agentmaxDOM k-tokens7586.0
2workarenaworkarena formbase_agentmaxDOM k-tokens1337341.0
3workarenaworkarena knowledgebase_agentmaxDOM k-tokens72976.0
4workarenaworkarena list-filterbase_agentmaxDOM k-tokens1442547.0
5workarenaworkarena list-sortbase_agentmaxDOM k-tokens1336066.0
6workarenaworkarena menubase_agentmaxDOM k-tokens270660.0
7workarenaworkarena service catalogbase_agentmaxDOM k-tokens1284051.0
8workarenaworkarena [ALL TASKS]base_agentmaxDOM k-tokens1442547.0
32miniwobminiwob [ALL TASKS]base_agentmaxAXTree k-tokens1009.0
34workarenaworkarena formbase_agentmaxAXTree k-tokens56093.0
35workarenaworkarena knowledgebase_agentmaxAXTree k-tokens6229.0
36workarenaworkarena list-filterbase_agentmaxAXTree k-tokens78882.0
37workarenaworkarena list-sortbase_agentmaxAXTree k-tokens83581.0
38workarenaworkarena menubase_agentmaxAXTree k-tokens14110.0
39workarenaworkarena service catalogbase_agentmaxAXTree k-tokens58863.0
40workarenaworkarena [ALL TASKS]base_agentmaxAXTree k-tokens83581.0
\n", - "
" - ], - "text/plain": [ - " benchmark Task group agent type obs \\\n", - "0 miniwob miniwob [ALL TASKS] base_agent max DOM k-tokens \n", - "2 workarena workarena form base_agent max DOM k-tokens \n", - "3 workarena workarena knowledge base_agent max DOM k-tokens \n", - "4 workarena workarena list-filter base_agent max DOM k-tokens \n", - "5 workarena workarena list-sort base_agent max DOM k-tokens \n", - "6 workarena workarena menu base_agent max DOM k-tokens \n", - "7 workarena workarena service catalog base_agent max DOM k-tokens \n", - "8 workarena workarena [ALL TASKS] base_agent max DOM k-tokens \n", - "32 miniwob miniwob [ALL TASKS] base_agent max AXTree k-tokens \n", - "34 workarena workarena form base_agent max AXTree k-tokens \n", - "35 workarena workarena knowledge base_agent max AXTree k-tokens \n", - "36 workarena workarena list-filter base_agent max AXTree k-tokens \n", - "37 workarena workarena list-sort base_agent max AXTree k-tokens \n", - "38 workarena workarena menu base_agent max AXTree k-tokens \n", - "39 workarena workarena service catalog base_agent max AXTree k-tokens \n", - "40 workarena workarena [ALL TASKS] base_agent max AXTree k-tokens \n", - "\n", - " value \n", - "0 7586.0 \n", - "2 1337341.0 \n", - "3 72976.0 \n", - "4 1442547.0 \n", - "5 1336066.0 \n", - "6 270660.0 \n", - "7 1284051.0 \n", - "8 1442547.0 \n", - "32 1009.0 \n", - "34 56093.0 \n", - "35 6229.0 \n", - "36 78882.0 \n", - "37 83581.0 \n", - "38 14110.0 \n", - "39 58863.0 \n", - "40 83581.0 " - ] - }, - "execution_count": 371, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 383, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 False\n", - "2 False\n", - "3 False\n", - "4 False\n", - "5 False\n", - "6 False\n", - "7 False\n", - "8 True\n", - "32 False\n", - "34 False\n", - "35 False\n", - "36 False\n", - "37 False\n", - "38 False\n", - "39 False\n", - "40 True\n", - "Name: Task group, dtype: bool" - ] - }, - "execution_count": 383, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_melt['Task group'] == \"workarena [ALL TASKS]\"" - ] - }, - { - "cell_type": "code", - "execution_count": 415, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " benchmark Task group agent type obs value\n", - "0 miniwob miniwob [ALL TASKS] base_agent max DOM k-tokens 7586.0\n", - "2 workarena workarena form base_agent max DOM k-tokens 1337341.0\n", - "3 workarena workarena knowledge base_agent max DOM k-tokens 72976.0\n", - "4 workarena workarena list-filter base_agent max DOM k-tokens 1442547.0\n", - "5 workarena workarena list-sort base_agent max DOM k-tokens 1336066.0\n", - " benchmark Task group agent type obs value\n", - "1 miniwob miniwob [ALL TASKS] full_agent max DOM k-tokens 9978.0\n", - "9 workarena workarena form full_agent max DOM k-tokens 1550687.0\n", - "10 workarena workarena knowledge full_agent max DOM k-tokens 178639.0\n", - "11 workarena workarena list-filter full_agent max DOM k-tokens 1593240.0\n", - "12 workarena workarena list-sort full_agent max DOM k-tokens 1493638.0\n" - ] - } - ], - "source": [ - "print(df_b.head())\n", - "print(df_f.head())" - ] - }, - { - "cell_type": "code", - "execution_count": 481, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " benchmark Task group agent type obs value\n", - "0 miniwob [ALL TASKS] base_agent max DOM k-tokens 7586.0\n", - "1 miniwob [ALL TASKS] full_agent max DOM k-tokens 9978.0\n", - "2 workarena form base_agent max DOM k-tokens 1337341.0\n", - "3 workarena knowledge base_agent max DOM k-tokens 72976.0\n", - "4 workarena list-filter base_agent max DOM k-tokens 1442547.0\n", - " benchmark Task group agent type obs value\n", - "0 miniwob miniwob [ALL TASKS] base_agent max DOM k-tokens 7586.0\n", - "1 miniwob miniwob [ALL TASKS] full_agent max DOM k-tokens 9978.0\n", - "2 workarena workarena form base_agent max DOM k-tokens 1337341.0\n", - "3 workarena workarena knowledge base_agent max DOM k-tokens 72976.0\n", - "4 workarena workarena list-filter base_agent max DOM k-tokens 1442547.0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\Tom\\AppData\\Local\\Temp\\ipykernel_38828\\1123958528.py:46: FutureWarning: \n", - "\n", - "The `ci` parameter is deprecated. Use `errorbar=None` for the same effect.\n", - "\n", - " sns.barplot(x='obs', y='value', hue='Task group', hue_order=sorted_task_group, data=df_b, order=None, palette=palette, ci=None)\n", - "C:\\Users\\Tom\\AppData\\Local\\Temp\\ipykernel_38828\\1123958528.py:50: FutureWarning: \n", - "\n", - "The `ci` parameter is deprecated. Use `errorbar=None` for the same effect.\n", - "\n", - " sns.barplot(x='obs', y='value', hue='Task group', hue_order=sorted_task_group, data=df_f, order=None, palette=[(0.75, 0.75, 0.7)], ci=None)\n", - "C:\\Users\\Tom\\AppData\\Local\\Temp\\ipykernel_38828\\1123958528.py:50: UserWarning: \n", - "The palette list has fewer values (1) than needed (7) and will cycle, which may produce an uninterpretable plot.\n", - " sns.barplot(x='obs', y='value', hue='Task group', hue_order=sorted_task_group, data=df_f, order=None, palette=[(0.75, 0.75, 0.7)], ci=None)\n", - "C:\\Users\\Tom\\AppData\\Local\\Temp\\ipykernel_38828\\1123958528.py:53: FutureWarning: \n", - "\n", - "The `ci` parameter is deprecated. Use `errorbar=None` for the same effect.\n", - "\n", - " sns.barplot(x='obs', y='value', hue='Task group', hue_order=sorted_task_group, data=df_b, order=None, palette=palette, ci=None)\n" - ] - }, - { - "ename": "PermissionError", - "evalue": "[Errno 13] Permission denied: 'wa_complexity_0.pdf'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mPermissionError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[481], line 68\u001b[0m\n\u001b[0;32m 64\u001b[0m \u001b[38;5;66;03m#put legend on top two rows aligned legend word on the right\u001b[39;00m\n\u001b[0;32m 66\u001b[0m legend1 \u001b[38;5;241m=\u001b[39m plt\u001b[38;5;241m.\u001b[39mlegend(loc\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mupper center\u001b[39m\u001b[38;5;124m'\u001b[39m, fontsize\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m16\u001b[39m, bbox_to_anchor\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m0.5\u001b[39m, \u001b[38;5;241m1.24\u001b[39m), ncol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m4\u001b[39m, labels\u001b[38;5;241m=\u001b[39m[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMiniWoB\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mknowledge\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmenu\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mservice catalog\u001b[39m\u001b[38;5;124m\"\u001b[39m,\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlist-sort\u001b[39m\u001b[38;5;124m\"\u001b[39m , \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mform\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlist-filter\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[1;32m---> 68\u001b[0m \u001b[43mplt\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msavefig\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43mf\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mwa_complexity_\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mi\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[38;5;124;43m.pdf\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdpi\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m300\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbbox_inches\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mtight\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 69\u001b[0m plt\u001b[38;5;241m.\u001b[39msavefig(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mwa_complexity_\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mi\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.png\u001b[39m\u001b[38;5;124m'\u001b[39m, dpi\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m300\u001b[39m, bbox_inches\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtight\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\pyplot.py:1119\u001b[0m, in \u001b[0;36msavefig\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 1116\u001b[0m fig \u001b[38;5;241m=\u001b[39m gcf()\n\u001b[0;32m 1117\u001b[0m \u001b[38;5;66;03m# savefig default implementation has no return, so mypy is unhappy\u001b[39;00m\n\u001b[0;32m 1118\u001b[0m \u001b[38;5;66;03m# presumably this is here because subclasses can return?\u001b[39;00m\n\u001b[1;32m-> 1119\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msavefig\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# type: ignore[func-returns-value]\u001b[39;00m\n\u001b[0;32m 1120\u001b[0m fig\u001b[38;5;241m.\u001b[39mcanvas\u001b[38;5;241m.\u001b[39mdraw_idle() \u001b[38;5;66;03m# Need this if 'transparent=True', to reset colors.\u001b[39;00m\n\u001b[0;32m 1121\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m res\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\figure.py:3390\u001b[0m, in \u001b[0;36mFigure.savefig\u001b[1;34m(self, fname, transparent, **kwargs)\u001b[0m\n\u001b[0;32m 3388\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ax \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39maxes:\n\u001b[0;32m 3389\u001b[0m _recursively_make_axes_transparent(stack, ax)\n\u001b[1;32m-> 3390\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcanvas\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprint_figure\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\backend_bases.py:2193\u001b[0m, in \u001b[0;36mFigureCanvasBase.print_figure\u001b[1;34m(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)\u001b[0m\n\u001b[0;32m 2189\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 2190\u001b[0m \u001b[38;5;66;03m# _get_renderer may change the figure dpi (as vector formats\u001b[39;00m\n\u001b[0;32m 2191\u001b[0m \u001b[38;5;66;03m# force the figure dpi to 72), so we need to set it again here.\u001b[39;00m\n\u001b[0;32m 2192\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m cbook\u001b[38;5;241m.\u001b[39m_setattr_cm(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfigure, dpi\u001b[38;5;241m=\u001b[39mdpi):\n\u001b[1;32m-> 2193\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mprint_method\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 2194\u001b[0m \u001b[43m \u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2195\u001b[0m \u001b[43m \u001b[49m\u001b[43mfacecolor\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfacecolor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2196\u001b[0m \u001b[43m \u001b[49m\u001b[43medgecolor\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43medgecolor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2197\u001b[0m \u001b[43m \u001b[49m\u001b[43morientation\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43morientation\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2198\u001b[0m \u001b[43m \u001b[49m\u001b[43mbbox_inches_restore\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_bbox_inches_restore\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2199\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2200\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[0;32m 2201\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m bbox_inches \u001b[38;5;129;01mand\u001b[39;00m restore_bbox:\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\backend_bases.py:2043\u001b[0m, in \u001b[0;36mFigureCanvasBase._switch_canvas_and_return_print_method..\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 2039\u001b[0m optional_kws \u001b[38;5;241m=\u001b[39m { \u001b[38;5;66;03m# Passed by print_figure for other renderers.\u001b[39;00m\n\u001b[0;32m 2040\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdpi\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfacecolor\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124medgecolor\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124morientation\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 2041\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbbox_inches_restore\u001b[39m\u001b[38;5;124m\"\u001b[39m}\n\u001b[0;32m 2042\u001b[0m skip \u001b[38;5;241m=\u001b[39m optional_kws \u001b[38;5;241m-\u001b[39m {\u001b[38;5;241m*\u001b[39minspect\u001b[38;5;241m.\u001b[39msignature(meth)\u001b[38;5;241m.\u001b[39mparameters}\n\u001b[1;32m-> 2043\u001b[0m print_method \u001b[38;5;241m=\u001b[39m functools\u001b[38;5;241m.\u001b[39mwraps(meth)(\u001b[38;5;28;01mlambda\u001b[39;00m \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: \u001b[43mmeth\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 2044\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43m{\u001b[49m\u001b[43mk\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mkwargs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mskip\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 2045\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m: \u001b[38;5;66;03m# Let third-parties do as they see fit.\u001b[39;00m\n\u001b[0;32m 2046\u001b[0m print_method \u001b[38;5;241m=\u001b[39m meth\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\backends\\backend_pdf.py:2800\u001b[0m, in \u001b[0;36mFigureCanvasPdf.print_pdf\u001b[1;34m(self, filename, bbox_inches_restore, metadata)\u001b[0m\n\u001b[0;32m 2798\u001b[0m file \u001b[38;5;241m=\u001b[39m filename\u001b[38;5;241m.\u001b[39m_ensure_file()\n\u001b[0;32m 2799\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 2800\u001b[0m file \u001b[38;5;241m=\u001b[39m \u001b[43mPdfFile\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2801\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 2802\u001b[0m file\u001b[38;5;241m.\u001b[39mnewPage(width, height)\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\backends\\backend_pdf.py:688\u001b[0m, in \u001b[0;36mPdfFile.__init__\u001b[1;34m(self, filename, metadata)\u001b[0m\n\u001b[0;32m 686\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moriginal_file_like \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 687\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtell_base \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[1;32m--> 688\u001b[0m fh, opened \u001b[38;5;241m=\u001b[39m \u001b[43mcbook\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_filehandle\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mwb\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreturn_opened\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 689\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m opened:\n\u001b[0;32m 690\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\cbook.py:483\u001b[0m, in \u001b[0;36mto_filehandle\u001b[1;34m(fname, flag, return_opened, encoding)\u001b[0m\n\u001b[0;32m 481\u001b[0m fh \u001b[38;5;241m=\u001b[39m bz2\u001b[38;5;241m.\u001b[39mBZ2File(fname, flag)\n\u001b[0;32m 482\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 483\u001b[0m fh \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mopen\u001b[39m(fname, flag, encoding\u001b[38;5;241m=\u001b[39mencoding)\n\u001b[0;32m 484\u001b[0m opened \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[0;32m 485\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(fname, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mseek\u001b[39m\u001b[38;5;124m'\u001b[39m):\n", - "\u001b[1;31mPermissionError\u001b[0m: [Errno 13] Permission denied: 'wa_complexity_0.pdf'" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3AAAAIECAYAAABYLsy0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACko0lEQVR4nOzdd1QUVxsG8Gd26SAoXQE7il1QmoolEk1MYtSIXawxxt5iosYSW9QvMSb2biyxETVijL3EKBYURMWCaKJIR5Bed74/CKuE6rC4rDy/c3JOmLk78yzOMPvu3LlXEEVRBBEREREREVV4MnUHICIiIiIiotJhAUdERERERKQhWMARERERERFpCBZwREREREREGoIFHBERERERkYZgAUdERERERKQhWMARERERERFpCBZwREREREREGkJL3QEqoqysLOTk5Kg7BhERERERvcXkcjm0tbVf6zUs4F6RmJiImJhYpKenqzsKERERERFVAnp6erCwMIexsXGp2guiKIrlnEkjJCYmIiwsDNraejA0NIJcztqWiIiIiIjKT05ONlJSkpGVlQ5bW9tSFXGsUv4VExMLbW09mJlZQhAEdcchIiIiIqK3ni709AwQFxeN2NjYUhVwHMQEuc+8paenw9DQiMUbERERERG9MYIgwMDACGlp6cjKyiqxPQs4QDlgCbtNEhERERHRm6allVuHlGYgRRZwREREREREGoIFHBERERERkYZgAUdERERERKQh+NBXKQmCAJlMswY4UShEcJYIqsg07bziOUWkGpp27gOacf6Loqhxg7FpYuZX8VguH+o6LjTleGQBVwqCIMDIWA9aMs26YZmtUCA5MV0lJ+mRI4excOE8AICxsQmOHj2pfNiyMLdvB2HkyKEAgObNW2LDhi0AADc3JwDAX39dLfb1xZk/fy6OHvXFjBmz8fHHPTFhwhhcvXoZU6ZMR58+/Qq0z8zMRNeunZCWloZatWpj794DhW538eIFOHz4IEaN+hzDh3/62rk2blyHzZs3FFguk8lgbGyM2rXr4L33uqF7956QadixVB4EQYBRFT1oyTXnd5Gdo0BykmrOKaLKShAEGBvradzfQYVCgUQVXVP/ex3Lu34MHToCo0ePlbTNK1f8sHPndqxcubbM+d6EnJwcHDzog3/++QdTp05XdxxJeCxXrGM5JOQBfvjhO9y7FwxR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Ojrw8/NDRkYGpk6dCgcHB3XHJCIiIiIikuytKeAAwMvLC9bW1tiwYQMCAwMhl8vRuHFjDB8+XDnAChERERERkabSqAJuyZIlWLJkSbFtPDw83sjIl0RERERERG+apGkEiIiIiIiI6M1jAUdERERERKQhWMARERERERFpCBZwREREREREGkLSICbe3t4lthEEAVpaWqhSpQpq1aqFd999F02bNpWyOyIiIiIiIoLEAu7q1asAcos0URQLbfPfdRs3bsS4ceMwZswYKbskIiIiIiKq9CQVcKdOncK0adNw8+ZN9OrVC++//z5sbW0hiiIiIyNx6tQp7Nu3DzY2Npg2bRqePXuGLVu2YOXKlWjZsiXatGmj6vdBRERERET01pNUwB05cgQ3b97EsmXL8NFHH+VbV7duXbRp0wYeHh74/PPP8fTpUwwfPhwdO3bEhx9+iF27drGAIyIiIiIikkDSICYHDhxA06ZNCxRvr+rUqRMcHR2xd+9eAEDt2rXh6OiIoKAgaUmJiIiIiIgqOUkFXFRUFGxsbEpsZ2lpiYiICOXP5ubmePHihZRdEhERERERVXqSCjgrKysEBgYiKyuryDZZWVm4efMmzMzMlMvi4+NRrVo1KbskIiIiIiKq9CQVcF27dkVkZCRmzpyJjIyMAuszMjLw9ddfIyoqCp07dwYAPHv2DNevX4e9vX3ZEhMREREREVVSkgYxGTVqFM6ePQtfX19cuHABbdu2RY0aNaBQKBAeHg4/Pz8kJCSgZs2aGDduHF68eIHu3bsjOzsbXl5eqn4PRERERERElYKkAq5KlSrYvn07li5dCl9fX/z+++/51stkMnzwwQeYOXMmqlatirt37yIjIwNDhw5F165dVRKciIiIiIiospFUwAGAqakpli5diq+++gpXrlxBREQEsrKyUL16dbi4uMDKykrZtl69evD394eenp5KQhMREREREVVGkgu4PNWqVcN7771XbBsdHZ2y7oaIiIiIiKjSK1MBFxMTg927d+Pq1auIiYmBjo4OzMzM4Orqih49eqB69eqqyklERERERFTpSS7gzp8/j6lTpyIlJQWiKCqXh4SE4MqVK9i0aROWLVumHIWSiIiIiIiIykZSARcaGoqJEyciIyMDPXr0wAcffABbW1vk5OQgLCwMR48exeHDhzFt2jQcOHAAderUUXVuIiIiIiKi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KXZC723btiEsLAweHh6SwxEREREREdFLkgYxGT16NP744w8sXrwYly9fhouLCwAgOjoaPj4++PPPP3Hy5EkYGxvj008/VWlgIiIiIiKiykpSAWdhYYEtW7ZgwoQJOH36tHKqgCtXruDKlSsQRREWFhb46aefUKNGDZUGJiIiIiIiqqwkT+Tt4OCAo0eP4sSJE7hy5QoiIiKQk5MDS0tLODs7o1u3btDT01NlViIiIiIiokpNcgEHAFpaWujWrRu6detWZJuMjAzo6uqWZTdEREREREQEiYOYnDp1qlTtLl26hA8//FDKLoiIiIiIiOg/JBVwkyZNwsmTJ4tcn5iYiBkzZmDEiBEICwuTHI6IiIiIiIheklTAyeVyTJ48GcePHy+w7ujRo+jWrRsOHToEHR0dTJw4scwhiYiIiIiISGIBt2nTJujo6GDq1Kn4448/AABRUVH4/PPPMXXqVMTGxqJNmzY4cuQIRo8erdLARERERERElZWkQUycnZ2xbds2fPrpp/jiiy9w7do1HD58GMnJyTA3N8fMmTOLHdiEiIiIiIiIXp+kO3AA0Lx5c2zfvh0mJibYvXs30tLSMGDAABw7dozFGxERERERUTmQXMABQMOGDfHLL7/A2toaoiiiSZMmMDIyUlU2IiIiIiIiekWpulBOnz692PW2traIiIjA7NmzceHCBejo6CjXCYKApUuXli0lERERERERla6AO3z4cKk2plAocOzYsXzLWMARERERERGpRqkKuG+//ba8cxAREREREVEJSlXA9ezZs7xzEBERERERUQkkTSPwX0+fPkVMTAx0dHRgbm4Oa2trVWyWiIiIiIiIXlGmAm7Xrl3YtGkTIiMj8y23tbXFoEGDMGTIkDKFIyIiIiIiopckF3AzZszAoUOHIIoizM3NYWtrC4VCgbCwMDx9+hRLlizBnTt3sGzZMlXmJSIiIiIiqrQkFXC+vr44ePAg7OzssHjxYjg7O+dbf/nyZXz99dfw9fVF586d0bVrV5WEJSIiIiIiqswkTeS9Z88e6OrqYsuWLQWKNwBwc3PD1q1boa2tjT179pQ5JBEREREREUks4O7duwdnZ2fY2dkV2cbOzg4uLi64e/eu5HBERERERET0kqQCLjs7G/r6+iW209fXR3p6upRdEBERERER0X9IKuBq1qwJf39/pKWlFdkmNTUV/v7+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KuUgJh07diywLC0tDTExMRg8eDAsLS1hY2MDXV1dREdH4/HjxxBFEXXq1MGiRYuwefNmVecmIiIiIiKqdEpVwEVGRha7PioqClFRUQWWP3r0CI8fP5aWjIiIiIiIiPIpVQF3+vTp8s5BREREREREJShVAWdjY1PeOYiIiIiIiKgEkgYxISIiIiIiojevVHfgCrNz507s3bsXT548QWZmZpHtBEFAcHCw1N0QERERERHRvyQVcLt378aiRYsgimKJbUvThoiIiIiIiEomqYDbtWsXZDIZZs+ejS5dusDY2BiCIKg6GxEREREREb1CUgEXFhYGNzc39OvXT9V5iIiIiIiIqAiSBjGxsrJi10giIiIiIqI3TFIB17t3b1y/fh2hoaGqzkNERERERERFkNSFcsSIEbh//z769++PgQMHomHDhjAxMSmyvbu7u+SARERERERElEtSAZeRkYGMjAwkJiZi3bp1xbblNAJERERERESqIamA+/7773Hy5EkIgoC6devC1NRU1bmIiIiIiIjoPyQVcMePH4eRkRG2b9+Oxo0bqzoTERERERERFULSICaJiYlwdnZm8UZERERERPQGSSrg6tati4SEBBVHISIiIiIiouJIKuC8vb0REBCAc+fOqTgOERERERERFUXSM3DNmjVDx44dMWbMGHTs2BEtWrSAiYkJtLQK31zv3r3LFJKIiIiIiIgkFnAffvghBEGAKIo4c+YMzp49W2x7FnBERERERERlJ6mA69GjBwRBUHUWIiIiIiIiKoakAm7JkiWqzkFEREREREQlkDSICREREREREb15ku7A+fn5vVZ7d3d3KbshIiIiIiKiV0gq4IYNG/Zaz8DdvXtXym6IiIiIiIjoFZIKOGdn50KXKxQKJCYm4vHjx8jOzkbnzp1Rt27dMgUkIiIiIiKiXJIKuB07dhS7PikpCbNnz4afnx9mzJghKRgRERERERHlVy6DmFSpUgXLli2DlpYWfvjhh/LYBRERERERUaVTbqNQ6ujowMnJCZcuXSqvXRAREREREVUqkrpQllZsbCzS0tLKcxdERERUAplMgExW+sHH1ElTchIRqUu5FHA5OTnYs2cPAgIC0KxZs/LYBREREZWCTCagWjUDyGSc+pWI6G0gqYDr2LFjketycnKQmJiIzMxMCIKAwYMHS81GREREZZR7902G4OAApKQkqztOiapXt4WtbR11xyAiqrAkFXCRkZEltrG2tsbIkSPRvXt3KbsgIiIiFUpJSUZycqK6Y5QoIyNd3RGIiCo0SQXc6dOni1wnk8lgYGAAExMTyaGIiIiIiIioIEkFnI2NjapzEBERERERUQlUNoiJQqEoch0fnCYiIiIiIio7yQXcyZMnsWHDBoSEhCAjI6PIdoIgIDg4WOpuiIiIiIiI6F+SCrizZ89iwoQJEEWxxLalaUNEREREREQlk1TAbdy4EaIoYtiwYfD29oalpSXkcrmqsxEREREREdErJBVwd+/eRaNGjfDll1+qOg8REREREREVQdLoItra2rC1tVV1FiIiIiIiIiqGpAKuefPmuHPnDnJyclSdh4iIiIiIiIogqYCbMGECoqOj8d133xU7fQARERERERGpjqRn4AIDA+Hh4YFt27bB19cXTZo0gbGxMQRBKNBWEAQsXbq0zEGJiIiIiIgqO0kF3OLFiyEIAkRRRGxsLM6fP19kWxZwREREREREqiGpgPv2229VnYOIiIiIiIhKIKmA69mzp6pzEBERERERUQkkDWJCREREREREbx4LOCIiIiIiIg3BAo6IiIiIiEhDsIAjIiIiIiLSECzgiIiIiIiINESlLuCysrLwww8/oEOHDnB0dMTo0aPx9OlTdcciIiIiIiIqlKQCLjg4uFTtcnJysGrVKim7eCP+97//4ZdffsHYsWPx448/4sWLFxgyZAjS0tLUHY2IiIiIiKgASQVc3759sXHjxmLbPHz4EF5eXli9erWkYOUtNTUVe/bswfjx49GnTx+0b98e33//PZ49e4a//vpL3fGIiIiIiIgKkNyFcvny5Rg8eDAiIyPzLRdFERs3bkSvXr0QHByMWrVqlTlkedDV1cXevXvx8ccfK5dpa2sDADIzM9UVi4iIiIiIqEiSCrgDBw7AwcEB165dQ/fu3XHkyBEAwN9//43+/ftj+fLlUCgUGD16NA4fPqzSwKoil8vRqFEjmJiYICcnB48ePcKsWbNgZWWF9u3bqzseERERERFRAVpSXmRvb4/9+/dj1apV2LRpE7744gscOHAAAQEBSEtLQ8uWLTF//nw0aNBA1XnLxffff4/NmzdDJpNh2bJlqFKlirojERERERERFSCpgAMALS0tTJo0CS4uLvj000/h5+cHAOjWrRuWL1+usoBvQvfu3dGh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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "import random\n", - "\n", - "for i in range(0,10):\n", - " df_melt = df.melt(id_vars=['benchmark', 'Task group', 'agent'], \n", - " value_vars=['max DOM k-tokens', 'max Pruned DOM k-tokens', 'max AXTree k-tokens', 'episode DOM k-tokens', 'episode Pruned DOM k-tokens', 'episode AXTree k-tokens'], \n", - " var_name='experience', value_name='value')\n", - " #take all value and multiply by 1000\n", - " df_melt['value'] = df_melt['value'] * 1000\n", - "\n", - " df_melt[['type', 'obs']] = df_melt['experience'].str.split(' ', n=1, expand=True)\n", - " #drop columns\n", - " df_melt = df_melt.drop(columns=['experience'])\n", - " #rearraange columns\n", - " df_melt = df_melt[['benchmark', 'Task group', 'agent', 'type', 'obs', 'value']]\n", - " sorted_obs = df_melt.groupby('obs')['value'].mean().sort_values().index\n", - "\n", - " print(df_melt.head())\n", - "\n", - " #drop lines where obs contains 'pruned'\n", - " df_melt = df_melt[~df_melt['obs'].str.contains('Pruned')]\n", - "\n", - " #keeping only max \n", - " df_melt = df_melt.loc[df_melt['type'] == 'max']\n", - " #df_melt = df_melt.loc[df_melt['agent'] == 'base_agent']\n", - " df_melt['Task group'] = df_melt['benchmark'] + ' ' + df_melt['Task group']\n", - " #remove lines where task group = \"workarena [ALL TASKS]\"\n", - " df_melt = df_melt[df_melt['Task group'] != \"workarena [ALL TASKS]\"]\n", - " # Create the bar plot\n", - " # Create a sorted list of 'obs' values based on the mean 'value'\n", - "\n", - " # Change the order of 'obs' in df_melt based on sorted_obs\n", - " sns.set_style(\"darkgrid\")\n", - " np.random.seed(random.randint(0, 100))\n", - "\n", - " # Create a color palette with a random seed\n", - " palette = sns.color_palette('colorblind', n_colors=len(df_melt['Task group'].unique()))\n", - " random.shuffle(palette)\n", - " palette_grey = sns.color_palette('grey', n_colors=1)\n", - " print(df_melt.head())\n", - " # Sort df_melt by 'obs'\n", - " sorted_task_group = df_melt.groupby(['Task group'])['value'].mean().sort_values().index.get_level_values('Task group')\n", - " figure = plt.figure(figsize=(10, 5))\n", - " df_b = df_melt.loc[df_melt['agent'] == 'base_agent']\n", - " sns.barplot(x='obs', y='value', hue='Task group', hue_order=sorted_task_group, data=df_b, order=None, palette=palette, ci=None)\n", - "\n", - " # Create the bar plot with sorted 'obs' categories\n", - " df_f = df_melt.loc[df_melt['agent'] == 'full_agent']\n", - " sns.barplot(x='obs', y='value', hue='Task group', hue_order=sorted_task_group, data=df_f, order=None, palette=[(0.75, 0.75, 0.7)], ci=None)\n", - "\n", - " df_b = df_melt.loc[df_melt['agent'] == 'base_agent']\n", - " sns.barplot(x='obs', y='value', hue='Task group', hue_order=sorted_task_group, data=df_b, order=None, palette=palette, ci=None)\n", - "\n", - " plt.ylabel('Max number of token per step (log scale)', fontsize=16)\n", - " plt.xlabel('')\n", - " #custom x tick labels\n", - " plt.xticks([0, 1], ['Document Object Model', 'Accessibility Tree'] , fontsize=16)\n", - " plt.yticks(fontsize=16)\n", - "\n", - " #y axis log\n", - " plt.yscale('log')\n", - "\n", - " #put legend on top two rows aligned legend word on the right\n", - "\n", - " legend1 = plt.legend(loc='upper center', fontsize=16, bbox_to_anchor=(0.5, 1.24), ncol=4, labels=[\"MiniWoB\", \"knowledge\", \"menu\", \"service catalog\",\"list-sort\" , \"form\", \"list-filter\"])\n", - "\n", - " plt.savefig(f'wa_complexity_{i}.pdf', dpi=300, bbox_inches='tight')\n", - " plt.savefig(f'wa_complexity_{i}.png', dpi=300, bbox_inches='tight')\n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 351, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\Tom\\AppData\\Local\\Temp\\ipykernel_38828\\25016155.py:4: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.\n", - " cmap = cm.get_cmap('viridis') # Replace 'viridis' with any colormap you like\n" - ] - }, - { - "ename": "ValueError", - "evalue": "shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 0 with shape (16,) and arg 1 with shape (4,).", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[351], line 15\u001b[0m\n\u001b[0;32m 13\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, label \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(labels):\n\u001b[0;32m 14\u001b[0m color \u001b[38;5;241m=\u001b[39m color_dict[label]\n\u001b[1;32m---> 15\u001b[0m rects1 \u001b[38;5;241m=\u001b[39m \u001b[43max\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbar\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mwidth\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mi\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mwidth\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgroup1_sorted\u001b[49m\u001b[43m[\u001b[49m\u001b[43mgroup1_sorted\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcolumns\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m\u001b[43m[\u001b[49m\u001b[43mgroup1_sorted\u001b[49m\u001b[43m[\u001b[49m\u001b[43mgroup1_sorted\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcolumns\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m==\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mlabel\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mwidth\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcolor\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcolor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlabel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlabel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 16\u001b[0m rects2 \u001b[38;5;241m=\u001b[39m ax\u001b[38;5;241m.\u001b[39mbar(x \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m10\u001b[39m\u001b[38;5;241m*\u001b[39mwidth \u001b[38;5;241m+\u001b[39m i\u001b[38;5;241m*\u001b[39mwidth, group1_sorted[group1_sorted\u001b[38;5;241m.\u001b[39mcolumns[\u001b[38;5;241m4\u001b[39m]][group1_sorted[group1_sorted\u001b[38;5;241m.\u001b[39mcolumns[\u001b[38;5;241m1\u001b[39m]] \u001b[38;5;241m==\u001b[39m label], width, color\u001b[38;5;241m=\u001b[39mcolor, label\u001b[38;5;241m=\u001b[39mlabel)\n\u001b[0;32m 18\u001b[0m \u001b[38;5;66;03m# Display the legend\u001b[39;00m\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\__init__.py:1478\u001b[0m, in \u001b[0;36m_preprocess_data..inner\u001b[1;34m(ax, data, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1475\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(func)\n\u001b[0;32m 1476\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minner\u001b[39m(ax, \u001b[38;5;241m*\u001b[39margs, data\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m 1477\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m data \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m-> 1478\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43max\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;28;43mmap\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43msanitize_sequence\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1480\u001b[0m bound \u001b[38;5;241m=\u001b[39m new_sig\u001b[38;5;241m.\u001b[39mbind(ax, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 1481\u001b[0m auto_label \u001b[38;5;241m=\u001b[39m (bound\u001b[38;5;241m.\u001b[39marguments\u001b[38;5;241m.\u001b[39mget(label_namer)\n\u001b[0;32m 1482\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m bound\u001b[38;5;241m.\u001b[39mkwargs\u001b[38;5;241m.\u001b[39mget(label_namer))\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\matplotlib\\axes\\_axes.py:2457\u001b[0m, in \u001b[0;36mAxes.bar\u001b[1;34m(self, x, height, width, bottom, align, **kwargs)\u001b[0m\n\u001b[0;32m 2454\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m yerr \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 2455\u001b[0m yerr \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_convert_dx(yerr, y0, y, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconvert_yunits)\n\u001b[1;32m-> 2457\u001b[0m x, height, width, y, linewidth, hatch \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbroadcast_arrays\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 2458\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Make args iterable too.\u001b[39;49;00m\n\u001b[0;32m 2459\u001b[0m \u001b[43m \u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43matleast_1d\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mheight\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mwidth\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlinewidth\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mhatch\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2461\u001b[0m \u001b[38;5;66;03m# Now that units have been converted, set the tick locations.\u001b[39;00m\n\u001b[0;32m 2462\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m orientation \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mvertical\u001b[39m\u001b[38;5;124m'\u001b[39m:\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\numpy\\lib\\stride_tricks.py:540\u001b[0m, in \u001b[0;36mbroadcast_arrays\u001b[1;34m(subok, *args)\u001b[0m\n\u001b[0;32m 533\u001b[0m \u001b[38;5;66;03m# nditer is not used here to avoid the limit of 32 arrays.\u001b[39;00m\n\u001b[0;32m 534\u001b[0m \u001b[38;5;66;03m# Otherwise, something like the following one-liner would suffice:\u001b[39;00m\n\u001b[0;32m 535\u001b[0m \u001b[38;5;66;03m# return np.nditer(args, flags=['multi_index', 'zerosize_ok'],\u001b[39;00m\n\u001b[0;32m 536\u001b[0m \u001b[38;5;66;03m# order='C').itviews\u001b[39;00m\n\u001b[0;32m 538\u001b[0m args \u001b[38;5;241m=\u001b[39m [np\u001b[38;5;241m.\u001b[39marray(_m, copy\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, subok\u001b[38;5;241m=\u001b[39msubok) \u001b[38;5;28;01mfor\u001b[39;00m _m \u001b[38;5;129;01min\u001b[39;00m args]\n\u001b[1;32m--> 540\u001b[0m shape \u001b[38;5;241m=\u001b[39m \u001b[43m_broadcast_shape\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 542\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mall\u001b[39m(array\u001b[38;5;241m.\u001b[39mshape \u001b[38;5;241m==\u001b[39m shape \u001b[38;5;28;01mfor\u001b[39;00m array \u001b[38;5;129;01min\u001b[39;00m args):\n\u001b[0;32m 543\u001b[0m \u001b[38;5;66;03m# Common case where nothing needs to be broadcasted.\u001b[39;00m\n\u001b[0;32m 544\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m args\n", - "File \u001b[1;32mc:\\Users\\Tom\\miniconda3\\envs\\ui-copilot\\Lib\\site-packages\\numpy\\lib\\stride_tricks.py:422\u001b[0m, in \u001b[0;36m_broadcast_shape\u001b[1;34m(*args)\u001b[0m\n\u001b[0;32m 417\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Returns the shape of the arrays that would result from broadcasting the\u001b[39;00m\n\u001b[0;32m 418\u001b[0m \u001b[38;5;124;03msupplied arrays against each other.\u001b[39;00m\n\u001b[0;32m 419\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 420\u001b[0m \u001b[38;5;66;03m# use the old-iterator because np.nditer does not handle size 0 arrays\u001b[39;00m\n\u001b[0;32m 421\u001b[0m \u001b[38;5;66;03m# consistently\u001b[39;00m\n\u001b[1;32m--> 422\u001b[0m b \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbroadcast\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m[\u001b[49m\u001b[43m:\u001b[49m\u001b[38;5;241;43m32\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 423\u001b[0m \u001b[38;5;66;03m# unfortunately, it cannot handle 32 or more arguments directly\u001b[39;00m\n\u001b[0;32m 424\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m pos \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m32\u001b[39m, \u001b[38;5;28mlen\u001b[39m(args), \u001b[38;5;241m31\u001b[39m):\n\u001b[0;32m 425\u001b[0m \u001b[38;5;66;03m# ironically, np.broadcast does not properly handle np.broadcast\u001b[39;00m\n\u001b[0;32m 426\u001b[0m \u001b[38;5;66;03m# objects (it treats them as scalars)\u001b[39;00m\n\u001b[0;32m 427\u001b[0m \u001b[38;5;66;03m# use broadcasting to avoid allocating the full array\u001b[39;00m\n", - "\u001b[1;31mValueError\u001b[0m: shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 0 with shape (16,) and arg 1 with shape (4,)." - ] - }, - { - "data": { - "image/png": "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Bx98MLq6uooyOAAw9uUKla6urti5c2ds3LgxamtrY8GCBbFmzZrYsWPHsHN3794dkyZNioceeihuuOGG2LhxY3zyk5/8P6MGAOD/Upbn5CNHjkR/f3/U19cPHmtoaIhnn302BgYGorT0f7vn0KFD0dDQECUlJRERUVJSEvPmzYuDBw/G8uXLL/ljlpRElHomzaj6cIVRWhqRZaM7y3hnF2mxj3TYRTou7KJYcoVKoVCIadOmxcSJEwePVVVVRW9vb5w5cyYqKiqGnDtr1qwh16+srIz29vZcA1ZUXJPrfK4eu0iHXaTFPtJhF2NPrvsquru7h0RKRAxe7uvru6RzP3oeAMDF5AqVSZMmDQuNC5fLy8sv6dyPngcAcDG5QqW6ujo6Ozujv79/8FihUIjy8vKYOnXqsHM7OjqGHOvo6Ijp06dfwbgAwHiSK1RqamqirKwsDh48OHispaUl5syZM+SJtBERdXV18fbbb0f24bOasiyLt956K+rq6q58agBgXMgVKpMnT46lS5dGU1NTtLa2xr59+6K5uTlWrVoVEefvXenp6YmIiIULF8YHH3wQW7ZsiWPHjsWWLVuiu7s7Fi1aVPzPAgAYk0qyLN8Lubq7u6OpqSn27t0bU6ZMidWrV8eXvvSliIi48cYb4/HHHx98+XFra2ts3rw53n333bjxxhvjkUceiZtvvrnonwQAMDblDhUAgJHin1IDAJIlVACAZAkVACBZoxoqvb29sWHDhpg/f340NjZGc3PzRc9955134u677466urq46667oq2tbQQnHfvy7OL111+PJUuWRH19fSxevDh+9KMfjeCkY1+eXVzwq1/9Kurr6+PNN98cgQnHlzz7OHr0aKxcuTLmzp0bixcvjjfeeGMEJx378uzihz/8YSxatCjq6+tj5cqVcfjw4RGcdPzo6+uLO++882N/91zx7Xc2ih599NFs8eLFWVtbW7Z3796svr4+e+2114add+7cuezWW2/NnnjiiezYsWPZY489ln3xi1/Mzp07NwpTj02Xuouf//znWW1tbbZ9+/bsl7/8ZfbCCy9ktbW12c9//vNRmHpsutRd/LbVq1dns2fPzt54440RmnL8uNR9fPDBB9kXv/jF7O///u+zX/7yl9nTTz+dNTQ0ZB0dHaMw9dh0qbv4z//8z2zOnDnZyy+/nB0/fjx75JFHsltv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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots()\n", - "labels = group1[group1.columns[1]].unique()\n", - "\n", - "cmap = cm.get_cmap('viridis') # Replace 'viridis' with any colormap you like\n", - "\n", - "# Create a normalized range of colors\n", - "colors = cmap(np.linspace(0, 1, len(labels)))\n", - "\n", - "# Create a dictionary that maps labels to colors\n", - "color_dict = dict(zip(labels, colors))\n", - "\n", - "# Create the bars with sorted data\n", - "for i, label in enumerate(labels):\n", - " color = color_dict[label]\n", - " rects1 = ax.bar(x - 10*width + i*width, group1_sorted[group1_sorted.columns[2]][group1_sorted[group1_sorted.columns[1]] == label], width, color=color, label=label)\n", - " rects2 = ax.bar(x + 10*width + i*width, group1_sorted[group1_sorted.columns[4]][group1_sorted[group1_sorted.columns[1]] == label], width, color=color, label=label)\n", - "\n", - "# Display the legend\n", - "ax.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 104, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "benchmark\n", - "miniwob [ALL TASKS]\n", - "miniwob [ALL TASKS]\n", - "workarena form\n", - "workarena knowledge\n", - "workarena list-filter\n", - "workarena list-sort\n", - "workarena menu\n", - "workarena service catalog\n", - "workarena [ALL TASKS]\n", - "workarena form\n", - "workarena knowledge\n", - "workarena list-filter\n", - "workarena list-sort\n", - "workarena menu\n", - "workarena service catalog\n", - "workarena [ALL TASKS]\n", - "Name: Task group, dtype: object" - ] - }, - "execution_count": 104, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Split the dataframe into three groups\n", - "group1 = df[[df.columns[0], df.columns[1], df.columns[2], df.columns[3], df.columns[4], df.columns[8]]]\n", - "group2 = df[[df.columns[0], df.columns[1], df.columns[5], df.columns[6], df.columns[7], df.columns[8]]]\n", - "\n", - "# Sort the data by the desired column\n", - "group1_sorted = group1.sort_values(by=group1.columns[2])\n", - "\n", - "# Create positions for the bars\n", - "x = np.arange(len(group1_sorted[group1_sorted.columns[1]]))\n", - "\n", - "# Plotting group1\n", - "fig, ax = plt.subplots()\n", - "\n", - "\n", - "# Create the bars with sorted data\n", - "import pandas as pd\n", - "\n", - "# Reshape the data\n", - "group1_sorted_melt = pd.melt(group1_sorted, id_vars=[group1_sorted.columns[0], group1_sorted.columns[5]], \n", - " value_vars=[group1_sorted.columns[2], group1_sorted.columns[4]], \n", - " var_name='variable', value_name='value')\n", - "\n", - "# Create the bar plot\n", - "sns.barplot(x=group1_sorted_melt[group1_sorted.columns[5]], y='value', hue='value', data=group1_sorted_melt, palette='colorblind')\n", - "# Display the legend\n", - "handles, _ = ax.get_legend_handles_labels()\n", - "ax.legend(handles, labels.unique(), title='Labels')\n", - "\n", - "# Add labels and title\n", - "ax.set_ylabel('Count')\n", - "ax.set_title('Group 1 Bar Plot')\n", - "ax.set_xticklabels(group1[group1.columns[1]])\n", - "\n", - "# Display the plot\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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j3N8WbeROR+O+FTSjBkzdPvtt5e6t0JkZKTGjh2rJUuW6Oabb5Z08gvizHtdhIWFKTIyUpL0888/lxofFRWlevXqlbueffv2aeHChfroo49K1TR06FD1799fBw4c0FdffaX33ntPAwcOVExMjIwxWrhwoT7++GPnB+GZHnvsMXl4eGjw4MEqKSnRXXfdpfHjx+vo0aPq1auXoqKidOjQIb3yyisqKipyObJ0oerWrauRI0dqzJgxCg0NVZMmTfTiiy/q6NGjGj58eJWtp6rExMTo888/V0JCgjw9Pct1j5UrrrhC/fr104gRI/TXv/5VgYGBevTRR3XppZeqX79+zukSEhL00EMPqV27ds4jKNddd51mz56tMWPGnHX5gwcP1ksvvaR+/fppwoQJaty4sX744Qd9+OGHevjhh9W4cWPdf//9ev7553XFFVfoyiuv1JQpU3To0CHnMgIDA5WUlOR8HRo0aKBx48apTp06zv+yY2JiNHjwYA0dOlSTJ09W27ZttW/fPmVmZqpVq1bO/eFsTv3D0KFDB/n7++udd96Rn5+foqKiJJ0M1itWrNDAgQPl4+Oj+vXrn7dtyys6Olpff/21tm/f7jwVmJycrOnTp+uuu+5yXvWTm5ur9957T2+99dY5Q0FVqYo2OXbsmMaMGaPbb79dl112mX766SdlZWXptttukyQ99NBDio+P18SJEzVgwACtXr1ar7322nmvBGrQoIH8/Py0ZMkSNW7cWL6+vs5batQEVfH6+fn56ZprrtHzzz+v/Px8ZWZm6quvvpIkrVy5Uvv27VOLFi0kSU899ZRGjx6t4OBg3XTTTSosLNSaNWt08OBBpaamnnM91113nRo2bKjBgwfrsssuK3W05nQpKSl69dVXNXDgQI0dO1bBwcH617/+pfbt26t58+YVrsPX11ePPPKIHn74YXl7e6tTp07at2+fNm7cqOHDh+uKK67Qjz/+qPfee0/x8fFavHix5s+f77KM6Ohobdu2TdnZ2WrcuLHzCruioiK9+uqr6tOnj1atWqVp06adsx3GjBmjO++8U23btlViYqIWLlyoDz/80Hnblu7du6tZs2ZKSkrSiy++qMOHD+vxxx+XpHNe1VhKuXsDWezMjo9r1qxxXjVSlp49e5r+/fsbY052opRU6jF8+HBjzMlOg2WN//vf/37Oms7sTDZp0iQTEhJSZoe3wsJCExISYv7yl7+YrVu3mhEjRpiYmBjj5+dnQkJCTHx8vMsVHGfrtPjCCy8YDw8PM3v2bLNs2TJz2223mcjISOPt7W3Cw8PNTTfdZFauXHne9juf0zs3G2PMsWPHzKhRo0z9+vWNj4+P6dSpk0vbn+rcfPDgwfOut6zOoKpgx7iynLmunJwc06BBA5OamlpmB/f777/fpSP8gQMHzN13322Cg4ONn5+f6dGjh8uVUMb8r9PuqY6XxpxsK0lmyZIl59ymXbt2maFDhzrbsGnTpmbEiBEmLy/PGHOyM/P9999vgoKCTEhIiElNTTVDhw51qTs/P98MGjTI+Pv7m4YNG5opU6aY9u3bm0cffdQ5zfHjx82TTz5poqOjjZeXl4mIiDD9+/c33377bZltdfrrMX/+fNOhQwcTFBRk6tata6655hqTkZHhnG/16tWmVatWxsfHx5zro6synZs3b95srrnmGuPn5+cy75YtW0z//v1NSEiI8fPzM1deeaV54IEHnB3FK/rePpvqbJPCwkIzcOBA577aqFEjk5KSYo4dO+acZt68eSY2NtZ4eXmZJk2amJdeesllGWfrRD19+nQTGRlp6tSpU+rCjqpWmf25Mq9fv379TFJSkvN5Tk6O6dixo/Hx8TGBgYEmODjYSDKRkZHm1VdfdZl39uzZpk2bNsbb29vUq1fPXHfddebDDz80xpy/M/jDDz9sJJknn3zSZXhZ861fv97ceOONxt/f3wQGBpouXbqYrVu3lquOshQXF5unn37aREVFOd8Dzz77rHP8mDFjTFhYmAkICDADBgwwL7/8skun5F9//dXcdtttJiQkxEhyfp9MmTLFREREOD/T3n77bZfP6jM7NxtjzOuvv26aNm1qvLy8TExMTKkrpTdt2mQ6depkvL29zZVXXmkWLlxY5mfguTiMOeNmHSglISFBbdq04TbylUT7/TYVFBTo0ksv1eTJk2vk0TcAv32rVq1S586dlZubq2bNmpVrHvr4lNPrr7+ugICAUlc+4exmz56tgIAArVy50t2loAr8+9//1rvvvqutW7dq3bp1zn4Ip5+OA4DqNH/+fC1dulTbt29XRkaG7rvvPnXq1KncoUeij0+5zJ4923lH5iZNmri5mtqjb9++znPV7vghOlS9SZMmafPmzfL29lZcXJxWrlxZpX1tAOBcDh8+rEceeUQ//vij6tevr8TExPNeYXYmTnUBAABrcKoLAABYg+ADAACsQfABAADWIPgAAABrEHwAAIA1CD4AAMAaBB8AAGANgg8AALDG/wNiKio7uZhuewAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Group 1 plot\n", - "fig, ax = plt.subplots()\n", - "\n", - "ax.set_yscale('log') # Apply log scale on y-axis\n", - "plt.title('Max')\n", - "plt.ylabel('Count')\n", - "plt.show()\n", - "\n", - "# Add spacing between plots\n", - "plt.subplots_adjust(hspace=0.5)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 98, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAICCAYAAAAu4dIrAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABj50lEQVR4nO3deVxN+f8H8Ndt30ulEqkQslOYbGU0tuxmbFmGBkMh2WesMdOMNUm2QZZsM2OZLzO2kC1bhMEkRAbVzKBkqdTn94dH5+dqkbTcOq/n43Ee434+n3Nen3PL3LezXYUQQoCIiIhIxtRKewJEREREpY0FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FERGVG25ubnBzcyvtaais2bNnQ6FQ4N9//y2V/GPHjkGhUOCXX34plXyi/LAgInpLaGgoFAoFFAoFTp48maNfCAEbGxsoFAp06dKlxOfn5uYmzU9NTQ1GRkaoVasWBg0ahEOHDuW5XkZGBoKCgtC0aVMYGhrCwMAATZs2RVBQEDIyMnKMt7Ozg0KhgLu7e67bW7NmjTSPCxcuFNn+lbTMzExYW1tDoVDgjz/+yNEvhEDr1q1RsWJF/Pfffzn6v/76a2hqaiI6Olp6P963HDt2rAT2rHiEhIQgNDS0tKdBVCw0SnsCRKpIR0cHW7ZsQatWrZTaIyIi8Pfff0NbW7uUZgZUqVIFAQEBAIDnz5/j1q1b2LlzJzZv3ow+ffpg8+bN0NTUlMY/f/4cHh4eiIiIQJcuXfDll19CTU0N+/fvx7hx47Bz507s27cP+vr6Sjk6Ojo4evQoEhISYGVlpdQXFhYGHR0dvHr1qvh3uBgdOXIEjx49gp2dHcLCwtCpUyelfoVCgVWrVqFRo0aYOHEi1q9fL/VFRkZi9erV8PPzQ6NGjbBp0yaldTdu3IhDhw7laHd0dCy+HSpmISEhMDc3x5dfflnaUyEqeoKIJOvXrxcARK9evYS5ubnIyMhQ6h8+fLhwcnIStra2wsPDo8Tn5+rqKurWrZuj/fXr12L06NECgJg8ebJS34gRIwQAsWzZshzrBQcHCwDi66+/Vmq3tbUV7dq1E0ZGRiIwMFCp7/79+0JNTU307t1bABDnz58vgj0rGq6ursLV1bXA4wcPHiyaNGkili5dKvT19UVqamqu47755hsBQBw7dkwIIUR6erqoV6+eqFq1ap7reHt7i4L8L/b58+cFnu/HmjVrlgAg/vnnn0KtX7du3Q96f9919OhRAUD8/PPPhd4GUXHhKTOiXPTv3x///fef0mmo9PR0/PLLLxgwYECu6yxcuBAtWrSAmZkZdHV14eTklONaifXr10OhUGDdunVK7d9//z0UCgV+//33Qs1XXV0dQUFBqFOnDoKDg5GcnAwA+Pvvv7F27Vp8+umn8PHxybGet7c32rZti59++gl///23Up+Ojg569eqFLVu2KLVv3boVFSpUQIcOHQo0t8ePH2PixImoX78+DAwMYGRkhE6dOuHy5ctK47KvL9mxYwe+++47VKlSBTo6OmjXrh1u3bqVY7urV69G9erVoauri2bNmuHEiRMFmk+2ly9fYteuXejXrx/69OmDly9fYs+ePbmOnTFjBqpXr46RI0ciPT0dixYtwp9//ong4OAcR9by4+bmhnr16iEqKgpt2rSBnp4evvnmGwBAWloaZs2ahRo1akBbWxs2NjaYPHky0tLScmxn8+bNcHJygq6uLkxNTdGvXz/cv3//g/Y/271791CjRg3Uq1cPiYmJeY6zs7PDtWvXEBERIZ3+e/t6rTt37uCLL76Aqakp9PT08Mknn2Dfvn3vzU9LS0OXLl1gbGyM06dPAwCysrIQGBiIunXrQkdHB5aWlhg5ciSePHmSY05dunTByZMn0axZM+jo6KBatWrYuHGj0riMjAzMmTMHDg4O0NHRgZmZGVq1apXvaWaSodKuyIhUSfYRovPnz4sWLVqIQYMGSX27d+8Wampq4sGDB7keIapSpYoYPXq0CA4OFosXLxbNmjUTAMTevXuVxnXp0kUYGxuL+Ph4IYQQV65cEVpaWsLLy+u988vrCFG2uXPnKmWuXr1aABChoaHv3ec1a9ZIbdn7d/DgQQFA3Lp1S+pr1KiRGDlypNJ7lZ/z58+L6tWri6lTp4pVq1YJf39/UblyZWFsbCwePHggjcs+etC4cWPh5OQklixZImbPni309PREs2bNlLb5008/CQCiRYsWIigoSPj6+goTExNRrVq1Ah/B2LZtm1AoFNLP4dNPPxWdO3fOc/yBAwcEAOHl5SV0dXVFz549891+bkeIXF1dhZWVlahYsaIYM2aMWLVqldi9e7fIzMwU7du3F3p6esLX11esWrVK+Pj4CA0NDdG9e3elbcybN08oFArRt29fERISIubMmSPMzc2FnZ2dePLkSb5zevcI0a1bt0TVqlVFo0aN3nvUaNeuXaJKlSqidu3aYtOmTWLTpk3i4MGDQgghEhIShKWlpTA0NBTffvutWLx4sWjYsKFQU1MTO3fulLbx7hGiFy9eiM8++0xUqFBBnDt3Thr31VdfCQ0NDTF8+HCxcuVKMWXKFKGvry+aNm0q0tPTpXG2traiVq1awtLSUnzzzTciODhYNGnSRCgUCvHnn39K47755huhUCjE8OHDxZo1a8SiRYtE//79xQ8//JDvPpO8sCAiesvbH/LBwcHC0NBQvHjxQgghxBdffCHatm0rhBC5FkTZ47Jln1b59NNPldofPXokTE1NxWeffSbS0tJE48aNRdWqVUVycvJ75/e+gmjXrl0CgFi6dKkQQghfX18BQFy6dCnPdS5evCgACD8/P6kte/9ev34trKysxNy5c4UQQly/fl0AEBEREQUuiF69eiUyMzOV2uLi4oS2trbw9/eX2rI/LB0dHUVaWprUvnTpUgFAXL16VQjx5n21sLAQjRo1UhqXXfwVtCDq0qWLaNmypdL6GhoaIikpKc91+vfvLwAIQ0NDcf/+/Xy3n1dBBECsXLlSqX3Tpk1CTU1NnDhxQql95cqVAoA4deqUEEKIu3fvCnV1dfHdd98pjbt69arQ0NDI0f6utwuiGzduCGtra9G0aVPx+PHjfNfLltcps+zfs7fn/+zZM2Fvby/s7Oykn//bBdGzZ8+Eq6urMDc3V/r9PHHihAAgwsLClDL279+fo93W1lYAEMePH5fakpKShLa2tpgwYYLU1rBhw1I5xU1lC0+ZEeUh+zTK3r178ezZM+zduzfP02UAoKurK/35yZMnSE5ORuvWrXHx4kWlcVZWVli+fDkOHTqE1q1bIzo6GuvWrYORkdFHz9nAwAAA8OzZM6X/Ghoa5rlOdl9KSkqOPnV1dfTp0wdbt24F8OZiahsbG7Ru3brAc9LW1oaa2pv/1WRmZuK///6DgYEBatWqleO9AYChQ4dCS0tLep2ddefOHQDAhQsXkJSUhK+//lpp3JdffgljY+MCzem///7DgQMH0L9/f6mtd+/e0im7vJibmwMA6tSpgypVqhQo613a2toYOnSoUtvPP/8MR0dH1K5dG//++6+0fPrppwCAo0ePAgB27tyJrKws9OnTR2mclZUVHBwcpHHv8+eff8LV1RV2dnY4fPgwKlSoUKh9yfb777+jWbNmSjchGBgYYMSIEbh79y6uX7+uND45ORnt27fHX3/9hWPHjqFRo0ZK74WxsTE+++wzpX10cnKCgYFBjn2sU6eO0u9jxYoVUatWLen3BQBMTExw7do1xMbGftR+UvnGu8yI8lCxYkW4u7tjy5YtePHiBTIzM/H555/nOX7v3r2YN28eoqOjla77UCgUOcb269cPmzdvxr59+zBixAi0a9euSOacmpoK4P+LnOz/ZhdGuXlf0TRgwAAEBQXh8uXL2LJlC/r165frPuUlKysLS5cuRUhICOLi4pCZmSn1mZmZ5RhftWpVpdfZH9bZ14/cu3cPAODg4KA0TlNTE9WqVSvQnLZv346MjAw0btxY6fqk5s2bIywsDN7e3jnWuXDhApYvX4569erh7Nmz2Lx5MwYOHFigvLdVrlxZqZADgNjYWNy4cQMVK1bMdZ2kpCRpnBAix75ne/vuwvx07doVlpaWOHDggFREZ0tNTZV+j4A3RXFe88p27949NG/ePEd79h119+7dQ7169aR2X19fvHr1CpcuXULdunWV1omNjUVycjIsLCxyzcp+L7K9+/sCvPmdeft6I39/f3Tv3h01a9ZEvXr10LFjRwwaNAgNGjTId79IXlgQEeVjwIABGD58OBISEtCpUyeYmJjkOu7EiRPo1q0b2rRpg5CQEFSqVAmamppYv359jouSgTdHKLKf33P9+nVkZWVJR1E+xp9//gkAqFGjBoD//0C6cuWK0r/C33blyhUAb/6lnZvmzZujevXq8PX1RVxcXL5HyXLz/fffY8aMGRg2bBjmzp0LU1NTqKmpwdfXF1lZWTnGq6ur57odIcQH5eYnLCwMANCyZctc++/cuaNUXGVmZmLEiBGwtrbGqVOn0L59e0yYMAFdunTJ83ciL28fScyWlZWF+vXrY/HixbmuY2NjI43LfmZSbu/Tu8VNXnr37o0NGzYgLCwMI0eOVOpbuHAh5syZI722tbXF3bt3C7TdgurevTu2bduGH374ARs3blT63c/KyoKFhYX0M3rXu8VZQX5f2rRpg9u3b2PPnj04ePAgfvrpJyxZsgQrV67EV199VQR7ROUBCyKifPTs2RMjR47E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OiV7e3tYWVkhPDxc6k9JScHZs2fh4uICAHBxccHTp08RFRUljTly5AiysrLQvHnzIpsrERERlV2FOkI0f/58eHh44PDhw1LhERkZifv37+P3338vssl17doV3333HapWrYq6devi0qVLWLx4MYYNGwYAUCgU8PX1xbx58+Dg4CDddm9tbY0ePXoAABwdHdGxY0cMHz4cK1euREZGBnx8fNCvX7887zAjIiIieSlUQeTq6oqbN29i+fLl+OuvvwAAvXr1wujRo4u0yFi2bBlmzJiB0aNHIykpCdbW1hg5ciRmzpwpjZk8eTKeP3+OESNG4OnTp2jVqhX2798vPYMIePNltD4+PmjXrh3U1NTQu3dvBAUFFdk8iYiIqGwrVEEUHx8PGxubXC+ejo+PR9WqVT96YgBgaGiIwMBABAYG5jlGoVDA398f/v7+eY4xNTXlQxiJiIgoT4W6hsje3h7//PNPjvb//vsP9vb2Hz0pIiIiopJUqIJICAGFQpGjPTU1VelUFREREVFZ8EGnzLIfVKhQKDBjxgzo6elJfZmZmTh79qx0uzsRERFRWfFBBdGlS5cAvDlCdPXqVWhpaUl9WlpaaNiwISZOnFi0MyQiIiIqZh9UEGV/4/3QoUOxdOlSGBkZFcukiIiIiEpSoa4hWr9+vVQMbd26Fc+fPy/SSRERERGVpEIVRG8bOXIkEhMTi2IuRERERKXiowsiIURRzIOIiIio1Hx0QURERERU1hWqINq6dav05z/++AOVK1eWXk+aNOnjZ0VERERUggpVEI0aNQp//PEHAKBVq1bQ1tYGAIwfPx6bN28uutkRERERlYBCFURhYWHo378/Tp48KbWNGTMGO3bskG7NJyIiIiorClUQeXh4ICQkBN26dUNUVBRGjx6NnTt34ujRo6hdu3ZRz5GIiIioWBXq2+4BYMCAAXj69ClatmyJihUrIiIiAjVq1CjKuRERERGViAIXRNnfY/auihUrokmTJggJCZHaFi9e/PEzIyIiIiohBS6Isr/H7F01atRASkqK1K9QKIpmZkREREQlpMAFES+WJiIiovKKD2YkIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkREREQkeyyIiIiISPZYEBEREZHssSAiIiIi2WNBRERERLLHgoiIiIhkjwURERERyR4LIiIiIpI9FkRE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JHssiIioRLm5ucHX17dU56BQKLB79+5SncPbQkNDS+RWZiLKGwsiIiIikj0WREREpSgjI6O0p0BEYEFERKXg9evX8PHxgbGxMczNzTFjxgxkPxItLS0NEydOROXKlaGvr4/mzZvj2LFj0rrZp5cOHDgAR0dHGBgYoGPHjnj06JFSxrp161C3bl1oa2ujUqVK8PHxUer/999/0bNnT+jp6cHBwQG//fab1Hfs2DEoFAocOHAAjRs3hq6uLj799FMkJSXhjz/+gKOjI4yMjDBgwAC8ePFCWm///v1o1aoVTExMYGZmhi5duuD27dtS/927d6FQKLB9+3a4urpCR0cHYWFhOd6ff/75B87OzujZsyfS0tI+6r0mooJhQUREJW7Dhg3Q0NDAuXPnsHTpUixevBg//fQTAMDHxweRkZHYtm0brly5gi+++AIdO3ZEbGystP6LFy+wcOFCbNq0CcePH0d8fDwmTpwo9a9YsQLe3t4YMWIErl69it9++w01atRQmsOcOXPQp08fXLlyBZ07d4anpyceP36sNGb27NkIDg7G6dOncf/+ffTp0weBgYHYsmUL9u3bh4MHD2LZsmXS+OfPn8PPzw8XLlxAeHg41NTU0LNnT2RlZSltd+rUqRg3bhxu3LiBDh06KPXdv38frVu3Rr169fDLL79AW1v7495sIiqYEn0uNhHJnqurq3B0dBRZWVlS25QpU4Sjo6O4d++eUFdXFw8ePFBap127dmLatGlCCCHWr18vAIhbt25J/cuXLxeWlpbSa2tra/Htt9/mOQcAYvr06dLr1NRUAUD88ccfQgghjh49KgCIw4cPS2MCAgIEAHH79m2pbeTIkaJDhw555vzzzz8CgLh69aoQQoi4uDgBQAQGBiqNW79+vTA2NhZ//fWXsLGxEWPHjlV6f4io+PEIERGVuE8++QQKhUJ67eLigtjYWFy9ehWZmZmoWbMmDAwMpCUiIkLp1JOenh6qV68uva5UqRKSkpIAAElJSXj48CHatWuX7xwaNGgg/VlfXx9GRkbSNnIbY2lpCT09PVSrVk2p7e11YmNj0b9/f1SrVg1GRkaws7MDAMTHxytt19nZOcd8Xr58idatW6NXr15YunSp0vtDRMVPo7QnQESULTU1Ferq6oiKioK6urpSn4GBgfRnTU1NpT6FQiFdg6Srq1ugrNy28e6prbfHKBSK967TtWtX2NraYs2aNbC2tkZWVhbq1auH9PR0pfX09fVzzEdbWxvu7u7Yu3cvJk2ahMqVKxdoP4ioaPAIERGVuLNnzyq9PnPmDBwcHNC4cWNkZmYiKSkJNWrUUFqsrKwKtG1DQ0PY2dkhPDy8OKaep//++w8xMTGYPn062rVrB0dHRzx58qTA66upqWHTpk1wcnJC27Zt8fDhw2KcLRG9iwUREZW4+Ph4+Pn5ISYmBlu3bsWyZcswbtw41KxZE56enhg8eDB27tyJuLg4nDt3DgEBAdi3b1+Btz979mwsWrQIQUFBiI2NxcWLF5Uufi4OFSpUgJmZGVavXo1bt27hyJEj8PPz+6BtqKurIywsDA0bNsSnn36KhISEYpotEb2LBRERlbjBgwfj5cuXaNasGby9vTFu3DiMGDECALB+/XoMHjwYEyZMQK1atdCjRw+cP38eVatWLfD2hwwZgsDAQISEhKBu3bro0qWL0l1qxUFNTQ3btm1DVFQU6tWrh/Hjx2PBggUfvB0NDQ1s3boVdevWlW71J6LipxDZJ96JiIiIZIpHiIiIiEj2WBARERGR7LEgIiIiItljQURERESyx4KIiIiIZI8FEREREckeCyIiIiKSPRZEREREJHssiIiIiEj2WBARERGR7LEgIiIiItn7P4e0CJ1+sWoiAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "df.set_index('benchmark', inplace=True)\n", - "\n", - "# Plot the 'max DOM k-tokens' and 'max AXTree k-tokens' columns\n", - "df[['max DOM k-tokens', 'max AXTree k-tokens']].plot(kind='bar')\n", - "\n", - "# Add labels and title\n", - "plt.ylabel('k-tokens')\n", - "plt.title('Max DOM and AXTree k-tokens')\n", - "\n", - "# Display the plot\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "ui-copilot", - "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.11.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/README.md b/README.md index 28343f8e..7472988e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ - - ![AgentLab Banner](https://github.com/user-attachments/assets/a23b3cd8-b5c4-4918-817b-654ae6468cb4) [![pypi](https://badge.fury.io/py/agentlab.svg)](https://pypi.org/project/agentlab/) @@ -10,6 +8,7 @@ [![Tests](https://github.com/ServiceNow/AgentLab/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/ServiceNow/AgentLab/actions/workflows/unit_tests.yml) + [🛠️ Setup](#%EF%B8%8F-setup-agentlab)  |  [🤖 Assistant](#-ui-assistant)  |  [🚀 Launch Experiments](#-launch-experiments)  |  @@ -48,6 +47,7 @@ AgentLab Features: | [Mind2Web-live](https://huggingface.co/datasets/iMeanAI/Mind2Web-Live) (soon) | - | - | None | - | - | live web | soon | | [MiniWoB](https://miniwob.farama.org/index.html) | [setup](https://github.com/ServiceNow/BrowserGym/blob/main/browsergym/miniwob/README.md) | 125 | Medium | 10 | no | self hosted (static files) | soon | + ## 🛠️ Setup AgentLab ```bash diff --git a/src/agentlab/analyze/error_categorization.py b/src/agentlab/analyze/error_categorization.py deleted file mode 100644 index c6a9cd1b..00000000 --- a/src/agentlab/analyze/error_categorization.py +++ /dev/null @@ -1,89 +0,0 @@ -import re - - -def is_critical_server_error(err_msg: str, stack_trace: str, return_error_type=False): - if stack_trace is None: - return False - server_error_conditions = [ - "502 Server Error: Bad Gateway", # url is not valid or server is not ready yet - "500 Server Error: Internal Server Error", # When the server is up, but somehow unresponsive - "424 Client Error: Failed Dependency", # Request failed during generation: Server error: CUDA error: invalid argument - "403 Client Error: Forbidden", - "401 Client Error: Unauthorized", # the server was auth-token protected - "400 Client Error: Bad Request", # there's no server. (the server probably failed) sometimes only visible in stack trace? - ] - if not return_error_type: - return any(condition in stack_trace for condition in server_error_conditions) - else: - for condition in server_error_conditions: - if condition in stack_trace: - return condition - return None - - -def is_minor_server_error(err_msg: str, stack_trace: str, return_error_type=False): - if stack_trace is None: - return False - server_error_conditions = [ - "504 Server Error: Gateway Time-out", - "Server error: Out of available cache blocks", # TODO(look into) - "openai.APIConnectionError: Connection error", - ] - if not return_error_type: - return any(condition in stack_trace for condition in server_error_conditions) - else: - for condition in server_error_conditions: - if condition in stack_trace: - return condition - return None - - -def is_retry_error(err_msg: str, stack_trace: str): - """Use regex on the stack trace to detect retry errors. - - The pattern is "ValueError: Could not parse a valid value after d+ - retries." - - Args: - err_msg (str): The error message - stack_trace (str): The stack trace - - Returns: - bool: True if the error is a retry error, False otherwise - """ - if stack_trace is None: - return False - pattern = r"ValueError: Could not parse a valid value after \d+ retries." - return re.search(pattern, stack_trace) is not None - - -def is_input_length_error(err_msg: str, stack_trace: str): - """Use regex on the stack trace to detect input length errors. - - The patterns are "422 Client Error: Unprocessable Entity" - and also "Input validation error: `inputs` tokens + `max_new_tokens` must be <=" - - Args: - err_msg (str): The error message - stack_trace (str): The stack trace - - Returns: - bool: True if the error is an input length error, False otherwise - """ - if stack_trace is None: - return False - patterns = [ - r"422 Client Error: Unprocessable Entity", - r"Input validation error: `inputs` tokens \+ `max_new_tokens` must be <=", - ] - return any( - re.search(pattern, err_msg) or re.search(pattern, stack_trace) for pattern in patterns - ) - - -ERR_CLASS_MAP = { - "critical_server_error": is_critical_server_error, - "minor_server_error": is_minor_server_error, - "retry_error": is_retry_error, - "input_length_error": is_input_length_error, -} diff --git a/src/agentlab/analyze/inspect_results.py b/src/agentlab/analyze/inspect_results.py index 862be27b..6dc3c3fc 100644 --- a/src/agentlab/analyze/inspect_results.py +++ b/src/agentlab/analyze/inspect_results.py @@ -1,12 +1,10 @@ import fnmatch -import io import json import random import re import traceback import warnings from collections import defaultdict -from datetime import datetime from logging import warn from pathlib import Path @@ -16,13 +14,7 @@ from IPython.display import display from tqdm import tqdm -from agentlab.analyze.error_categorization import ( - ERR_CLASS_MAP, - is_critical_server_error, - is_minor_server_error, -) from agentlab.experiments.exp_utils import RESULTS_DIR -from agentlab.utils.bootstrap import bootstrap_matrix, convert_df_to_array # TODO find a more portable way to code set_task_category_as_index at least # handle dynamic imports. We don't want to always import workarena @@ -30,11 +22,6 @@ warnings.filterwarnings("ignore", category=pd.errors.PerformanceWarning) -try: - import pyperclip -except ImportError: - pyperclip = None - pd.set_option("display.multi_sparse", False) AGENT_NAME_KEY = "agent.agent_name" @@ -224,18 +211,6 @@ def report_constant_and_variables(df, show_stack_traces=True): print(f" ...\n") -def get_bootstrap(df, metric, reduce_fn=np.nanmean, n_bootstrap=100, group_by=TASK_KEY, prior=0.5): - """Get the stratified bootstrap mean and std for the given metric.""" - grouped_df = df.reset_index(inplace=False).groupby(group_by) - array = convert_df_to_array(grouped_df, metric=metric, threshold=0.7) - if prior is not None: - prior = prior * np.ones((len(array), 1)) - array = np.concatenate([array, prior], axis=1) - - bootstrapped_values = bootstrap_matrix(array, n_bootstrap=n_bootstrap, reduce_fn=reduce_fn) - return np.nanmean(bootstrapped_values), np.nanstd(bootstrapped_values) - - def get_std_err(df, metric): """Get the standard error for a binary metric.""" # extract non missing values @@ -262,7 +237,7 @@ def get_sample_std_err(df, metric): return mean, std_err -def summarize(sub_df, use_bootstrap=False): +def summarize(sub_df): if not "cum_reward" in sub_df: record = dict( avg_reward=np.nan, @@ -279,10 +254,7 @@ def summarize(sub_df, use_bootstrap=False): if n_completed == 0: return None - if use_bootstrap: - _mean_reward, std_reward = get_bootstrap(sub_df, "cum_reward") - else: - _mean_reward, std_reward = get_std_err(sub_df, "cum_reward") + _mean_reward, std_reward = get_std_err(sub_df, "cum_reward") # sanity check, if there is an error the reward should be zero assert sub_df[sub_df["err_msg"].notnull()]["cum_reward"].sum() == 0 @@ -466,21 +438,6 @@ def _rename_bool_flags(report: pd.DataFrame, true_str="✓", false_str="-"): return report -def to_clipboard(df: pd.DataFrame): - """Copy the dataframe to the clipboard as a tab separated csv.""" - output = io.StringIO() - df.to_csv(output, sep="\t", index=True) - csv_string = output.getvalue() - if pyperclip is not None: - try: - pyperclip.copy(csv_string) - except Exception as e: - warn(f"Failed to copy to clipboard: {e}") - # else: - # print("pyperclip is not installed, cannot copy to clipboard.") - # return df - - def flag_report(report: pd.DataFrame, metric: str = "avg_reward", round_digits: int = 2): # for all index in the multi-index with boolean value, get the average for # True and the average for False separately. Produce a new dataframe with diff --git a/src/agentlab/analyze/plot_tools.py b/src/agentlab/analyze/plot_tools.py deleted file mode 100644 index b60f60df..00000000 --- a/src/agentlab/analyze/plot_tools.py +++ /dev/null @@ -1,409 +0,0 @@ -from pathlib import Path -from typing import List - -import joblib -import numpy as np -import pandas as pd -import seaborn as sns -from matplotlib import pyplot as plt -from matplotlib.collections import PolyCollection -from matplotlib.ticker import FormatStrFormatter -from scipy.stats import trim_mean - -from agentlab.utils.bootstrap import bootstrap_all_benchmarks - -sns.set_style("dark", {"grid.color": "0.98", "axes.facecolor": "(0.95, 0.95, 0.97)"}) - - -def load_benchmark_masks(csv_path: Path | str, benchmark_names=list[str]): - """Load benchmark masks from a csv file and convert it. - - To create the csv file simply use file/download/"...csv" from google - spreadsheet. - - Args: - csv_path (Path | str): The path to the csv file. - benchmark_names (list[str]): The names of the benchmarks to be loaded. - - Returns: - pd.DataFrame: The benchmark masks. - """ - mask_df = pd.read_csv(csv_path) # type: pd.DataFrame - - for benchmark_name in benchmark_names: - mask_df[benchmark_name] = mask_df[benchmark_name].apply( - lambda x: True if str(x).strip() == "x" else False - ) - - mask_df["all"] = True - benchmark_names = ["all"] + benchmark_names - - # remove the Average row - mask_df = mask_df[mask_df["Task Name"] != "ZAverage"] - mask_df = mask_df[mask_df["Task Name"].isna() == False] - - # # print the excluded tasks - # excluded_tasks = set(mask_df["Task Name"].unique()) - set(MINIWOB_TASKNAME_TO_CLASSNAME.keys()) - # print("Excluded tasks:", excluded_tasks) - - # # filter task that are not in the MINIWOB_TASKNAME_TO_CLASSNAME - # mask_df = mask_df[mask_df["Task Name"].isin(MINIWOB_TASKNAME_TO_CLASSNAME.keys())] - - # # convert task name to class name and keep all columns - mask_df["task_name"] = mask_df["Task Name"].apply(lambda x: f"miniwob.{x}") - mask_df.set_index("task_name", inplace=True) - - # extract only the benchmark columns - mask_df = mask_df[benchmark_names] - - # rename columns - mask_df.rename(rename_func, inplace=True, axis="columns") - return mask_df - - -def add_benchmark_masks(df: pd.DataFrame, benchmark_masks: pd.DataFrame): - """Add benchmark masks to the dataframe.""" - return df.merge(benchmark_masks, left_on="task_name", right_index=True) - - -def sort_agents(agents, df, metric="cum_reward"): - agent_order = ( - df.groupby("agent_model_name")[metric].mean().sort_values(ascending=False).index.tolist() - ) - return [agent for agent in agent_order if agent in agents] - - -def iqm(scores): - """Interquantile mean.""" - return trim_mean(scores, proportiontocut=0.25, axis=None) - - -# add memory from joblib -memory = joblib.Memory(location=Path().home() / "cache", verbose=1) -bootstrap_all_benchmarks_cached = memory.cache(bootstrap_all_benchmarks) - - -def bootstrap_and_plot( - df: pd.DataFrame, - benchmark_names: List[str], - metric: str = "cum_reward", - model_axis: str = "agent_model_name", - agent_order: List[str] | None = None, - agent_colors=None, - agent_markers=None, - repeat: int = 100, - fig_size=None, - n_legend_rows: int = 2, -): - """Add aggregated data as a new benchmark.""" - - if agent_order is None: - agent_order = sorted(df[model_axis].unique()) - print("bootstrapping") - # create a new df containing bootstrapped samples of iqm - - df_bootstrap = bootstrap_all_benchmarks( - df, metric, benchmark_cols=benchmark_names, repeat=repeat - ) - print("plotting") - - # plot results per benchmark (aggregated results is an extra benchmark) - plot_per_benchmark( - df_bootstrap, - agent_order, - model_axis, - benchmark_order=benchmark_names, - agent_colors=agent_colors, - agent_markers=agent_markers, - metric=metric, - fig_size=fig_size, - n_legend_rows=n_legend_rows, - ) - - -def remove_violin_outline(ax): - """Remove the outline of the violin plot.""" - for pc in ax.collections: - pc.set_edgecolor("none") - - -def get_violin_centers(ax: plt.Axes) -> list[float]: - """Estimate the center of violin patches from axes. - - This is a hacky way to get the center of the violin patches. - It works by averaging the x coordinates of the vertices of PolyCollection - - Args: - ax (plt.Axes): The axes containing the violin plot. - - Returns: - list[float]: The x coordinates of the centers of the violins. - """ - violin_centers = [] - for child in ax.get_children(): - if isinstance(child, PolyCollection): - violin_centers.append(np.mean(child.get_paths()[0].vertices[:, 0])) - - return sorted(violin_centers) - - -def associate_action_markers(agent_order): - """Associate a marker to each agent, based on action space.""" - markers = {} - for agent in agent_order: - marker = None - if "high" in agent: - marker = "^" - elif "low" in agent: - marker = "v" - elif "both" in agent: - marker = "d" - elif "code" in agent: - marker = "o" - else: - marker = "*" - - markers[agent] = marker - return markers - - -def rename_func(name): - return RENAME_DICT.get(name, name) - - -# for display names in the paper -RENAME_DICT = { - "easy (auto)": "easy", - "hard (auto)": "hard", - "long context (auto)": "long context", - "rci-agent task (47)": "RCI\nsubset", - "WebGUM task (56)": "WebGUM\nsubset", - "long context": "long context", - "pixel": "pixel", - "2d under standing": "2D\nunderstanding", - "x,y actions": "x, y\nactions", - "domain specific knowledge or exploration ?": "domain specific\nknowledge", - "long episode": "long episode", - "rapid interaction": "rapid interaction", - "action space limited": "action space\nlimited", - "requies augmented HTML and/or AXTree": "requires\naugmented HTML", -} - - -def add_markers(ax, df, model_axis, metric, agent_order, agent_markers, agent_colors): - """Add markers to the scatter plot.""" - v_centers = get_violin_centers(ax) - scatter_handles = {} - - for center_x, agent in zip(v_centers, agent_order): - median_y = df[df[model_axis] == agent][metric].mean() - - scatter_plot = ax.scatter( - center_x, - median_y, - marker=agent_markers[agent], - color=agent_colors[agent], - edgecolor="black", - label=agent, - s=60, - ) - - scatter_handles[agent] = scatter_plot - - # markers overtake the legend - legend = ax.legend( - handles=list(scatter_handles.values()), - labels=list(scatter_handles.keys()), - loc="lower center", - bbox_to_anchor=(0.5, 1), - ncol=len(agent_order), - title="", - ) - - # bigger markers! - for handle in legend.legendHandles: - handle.set_sizes([100]) - return scatter_handles - - -def plot_per_benchmark( - df: pd.DataFrame, - agent_order: List[str], - model_axis: str, - benchmark_order: List[str] | None = None, - metric: str = "cum_reward", - aggregated_name: str = "all", - sharey: bool = True, - inner: str = None, - fig_size: tuple = None, - n_legend_rows: int = 1, - agent_colors: dict[str, tuple] = None, - agent_markers: dict[str, str] = None, -): - """Violin plots for each benchmarks and each agents. - - Args: - df: pd.DataFrame - The input DataFrame. - agent_order: List[str] - The order of the agents in the plot. - model_axis: str - The column containing the agent names. - benchmark_order: List[str], optional - The order of the benchmarks in the plot. Defaults to alhpabetical order. - metric: str, optional - The column containing the metric to which the function will be applied. - aggregated_name: str, optional - The name of the "special" benchmark. It will be placed first and - highlighted in pale blue - sharey: bool, optional - Whether to share the y axis between plots. - inner: str, optional - The type of inner display inside of the violins. See seaborn.violinplot - fig_size: tuple, optional - The size of the figure. see matplotlib.pyplot.figure - n_legend_rows: int, optional - The number of rows in the legend. - agent_colors: dict[str, tuple], optional - A dictionary mapping agent names to colors. Defaults to seaborn's colorblind palette. - agent_markers: dict[str, str], optional - A dictionary mapping agent names to markers. Defaults to no markers. - """ - if benchmark_order is None: - benchmark_order = sorted(df["benchmark"].unique()) - - if fig_size is None: - fig_width = len(benchmark_order) * 2 - fig_size = (fig_width, 3) - fig, axes = plt.subplots(1, len(benchmark_order), sharey=sharey, figsize=fig_size) - - if agent_colors is None: - colors = sns.color_palette("colorblind", n_colors=len(agent_order)) - agent_colors = dict(zip(agent_order, colors)) - - if agent_markers is not None: - violon_palette = {agent: (0.8, 0.8, 0.8) for agent in agent_order} - else: - violon_palette = agent_colors - - for benchmark, ax in zip(benchmark_order, axes): - sub_df = df[df["benchmark"] == benchmark] - - sns.violinplot( - x="benchmark", - y=metric, - hue=model_axis, - data=sub_df, - hue_order=agent_order, - linewidth=0.5, - saturation=1, - scale="count", - inner=inner, - palette=violon_palette, - ax=ax, - ) - remove_violin_outline(ax) - - if agent_markers is not None: - add_markers(ax, sub_df, model_axis, metric, agent_order, agent_markers, agent_colors) - - ax.tick_params(axis="y", labelsize=18) - ax.yaxis.set_major_formatter(FormatStrFormatter("%.2f")) - ax.grid(axis="y") - - if benchmark == aggregated_name: - ax.set_facecolor("#cff6fc") - - ax.set(xlabel=None) - - if benchmark != benchmark_order[int((len(benchmark_order) - 1) / 2)]: - ax.get_legend().remove() - else: - ncols = int(np.ceil(len(agent_order) / n_legend_rows)) - - sns.move_legend(ax, loc="lower center", bbox_to_anchor=(0.5, 1), ncol=ncols, title="") - - if benchmark != benchmark_order[0]: - ax.set(ylabel=None) - - if sharey: - fig.subplots_adjust(wspace=0.02) - else: - fig.subplots_adjust(wspace=0.3) - - -@memory.cache -def modify_names(df): - """Generate names that are paper-friendly, and fix model_name and agent_name for the different formats.""" - - def process_row(row): - model_name = row.get("model_name", np.nan) - agent_name = row["agent_name"] - - if not isinstance(model_name, str) or len(model_name) == 0: - # rim's type of model extract from agent name - model_name = "gpt-4" if "gpt4" in agent_name else "gpt-3.5" - agent_name = agent_name.replace("_gpt4", "") - else: - # massimo's type of model - if "/" in model_name: - model_name = model_name.split("/")[-1] - model_name = model_name.replace("-Instruct-hf", "").replace("-beta", "") - - agent_name = agent_name.replace("GenericAgent_", "") - - row["agent_name"] = agent_name - row["model_name"] = model_name - row["agent_model_name"] = f"{agent_name}-{model_name}" - - return row - - return df.apply(process_row, axis=1) - - -def find_incomplete_exp(df: pd.DataFrame, agent_columns_to_show=None): - agents = df["agent_model_name"].unique() - # print(agents) - dicts = [] - for agent in agents: - agent_df = df[df["agent_model_name"] == agent] # type: pd.DataFrame - tasks = agent_df["task_name"].unique() - - n_episode = [] - for task in tasks: - task_df = agent_df[agent_df["task_name"] == task] - n_episode.append(len(task_df)) - # find missing cum_reward - missing_cum_reward = agent_df["cum_reward"].isna().sum() - # num results - num_results = len(agent_df) - - info = { - "agent": agent, - "n_tasks": len(tasks), - "max_ep_count": np.max(n_episode), - "min_ep_count": np.min(n_episode), - "mean_ep_count": np.mean(n_episode), - "unique cum_reward": str(agent_df["cum_reward"].unique()), - "missing_cum_reward": missing_cum_reward, - "total_results": num_results, - } - - if agent_columns_to_show is not None: - for col in agent_columns_to_show: - info[f"{col}-unique"] = agent_df[col].unique()[:10] - - for task in tasks: - sub_df = agent_df[agent_df["task_name"] == task] - if len(sub_df) > 10: - unique_exp_dir = sub_df["exp_dir"].unique() - print( - f" {agent} {task} {len(sub_df)} n unique expseeds {len(sub_df['exp_seed'].unique())}" - ) - for i, dir in enumerate(unique_exp_dir): - print(f" Unique exp_dir {i}: {dir}") - - dicts.append(info) - df_summary = pd.DataFrame(dicts) - # df_summary = df_summary.sort_values("max_episode_count", ascending=False) - return df_summary diff --git a/src/agentlab/experiments/get_ray_url.py b/src/agentlab/experiments/get_ray_url.py index b652254c..2eb5cb58 100644 --- a/src/agentlab/experiments/get_ray_url.py +++ b/src/agentlab/experiments/get_ray_url.py @@ -1,3 +1,8 @@ +"""Temporary script to get the ray dashboard url for the current experiment. + +TODO figure out a more convenient way. +""" + import ray context = ray.init(address="auto", ignore_reinit_error=True) diff --git a/src/agentlab/experiments/graph_execution_dask.py b/src/agentlab/experiments/graph_execution_dask.py deleted file mode 100644 index dc51dd51..00000000 --- a/src/agentlab/experiments/graph_execution_dask.py +++ /dev/null @@ -1,64 +0,0 @@ -from concurrent.futures import ThreadPoolExecutor, TimeoutError as FuturesTimeoutError - -from contextlib import contextmanager -import threading -from dask import compute, delayed -from bgym import ExpArgs -from distributed import LocalCluster, Client -from agentlab.experiments.exp_utils import _episode_timeout - -# from agentlab.experiments.exp_utils import run_exp - - -def run_exp(exp_arg: ExpArgs, *dependencies, avg_step_timeout=60): - """Run exp_args.run() with a timeout and handle dependencies.""" - # dask can't use the timeout_manager define in exp_utils.py - # ValueError: signal only works in main thread of the main interpreter - # most alternative I try doesn't work - episode_timeout = _episode_timeout(exp_arg, avg_step_timeout=avg_step_timeout) - return exp_arg.run() - - -def make_dask_client(n_worker): - """Create a Dask client with a LocalCluster backend. - - I struggled to find an appropriate configuration. - I believe it has to do with the interplay of playwright async loop (even if - used in sync mode) and the fact that dask uses asyncio under the hood. - Making sure we use processes and 1 thread per worker seems to work. - - Args: - n_worker: int - Number of workers to create. - - Returns: - A Dask client object. - """ - cluster = LocalCluster( - n_workers=n_worker, - processes=True, - threads_per_worker=1, - ) - - return Client(cluster) - - -def execute_task_graph(exp_args_list: list[ExpArgs]): - """Execute a task graph in parallel while respecting dependencies.""" - exp_args_map = {exp_args.exp_id: exp_args for exp_args in exp_args_list} - - tasks = {} - - def get_task(exp_arg: ExpArgs): - if exp_arg.exp_id not in tasks: - dependencies = [get_task(exp_args_map[dep_key]) for dep_key in exp_arg.depends_on] - tasks[exp_arg.exp_id] = delayed(run_exp)(exp_arg, *dependencies) - return tasks[exp_arg.exp_id] - - for exp_arg in exp_args_list: - get_task(exp_arg) - - task_ids, task_list = zip(*tasks.items()) - results = compute(*task_list) - - return {task_id: result for task_id, result in zip(task_ids, results)} diff --git a/src/agentlab/experiments/list_openai_models.py b/src/agentlab/experiments/list_openai_models.py index 438f97bd..0c301926 100644 --- a/src/agentlab/experiments/list_openai_models.py +++ b/src/agentlab/experiments/list_openai_models.py @@ -5,8 +5,8 @@ models = OpenAI().models.list() df = pd.DataFrame([dict(model) for model in models.data]) - # Filter GPT models - df = df[df["id"].str.contains("gpt")] + # Filter GPT models or o1 models + df = df[df["id"].str.contains("gpt") | df["id"].str.contains("o1")] # Convert Unix timestamps to dates (YYYY-MM-DD) and remove time df["created"] = pd.to_datetime(df["created"], unit="s").dt.date diff --git a/src/agentlab/experiments/miniwob_tasks_all.csv b/src/agentlab/experiments/miniwob_tasks_all.csv deleted file mode 100644 index e4b3777b..00000000 --- a/src/agentlab/experiments/miniwob_tasks_all.csv +++ /dev/null @@ -1,126 +0,0 @@ -task_name,miniwob_category,comment -ascending-numbers,hidden test, -bisect-angle,original, -book-flight,original,delay -book-flight-nodelay,nodelay, -buy-ticket,hidden test, -choose-date,original,delay -choose-date-easy,debug,delay -choose-date-medium,debug,delay -choose-date-nodelay,nodelay, -choose-list,original, -circle-center,original, -click-button,original, -click-button-sequence,original, -click-checkboxes,original, -click-checkboxes-large,additional, -click-checkboxes-soft,additional, -click-checkboxes-transfer,additional, -click-collapsible,original,delay -click-collapsible-2,original,delay -click-collapsible-2-nodelay,nodelay, -click-collapsible-nodelay,nodelay, -click-color,original, -click-dialog,original, -click-dialog-2,original, -click-link,original, -click-menu,original, -click-menu-2,original, -click-option,original, -click-pie,original,delay -click-pie-nodelay,nodelay, -click-scroll-list,original, -click-shades,original, -click-shape,original, -click-tab,original, -click-tab-2,original, -click-tab-2-easy,debug, -click-tab-2-hard,additional, -click-tab-2-medium,debug, -click-test,original, -click-test-2,original, -click-test-transfer,debug, -click-widget,original, -copy-paste,original, -copy-paste-2,original, -count-shape,original, -count-sides,original, -daily-calendar,hidden test, -drag-box,original, -drag-circle,original, -drag-cube,original, -drag-items,original, -drag-items-grid,original, -drag-shapes,original, -drag-shapes-2,hidden test, -drag-single-shape,hidden test, -drag-sort-numbers,original, -draw-circle,hidden test, -draw-line,hidden test, -email-inbox,original, -email-inbox-delete,debug, -email-inbox-forward,debug, -email-inbox-forward-nl,additional, -email-inbox-forward-nl-turk,additional, -email-inbox-important,debug, -email-inbox-nl-turk,additional, -email-inbox-noscroll,debug, -email-inbox-reply,debug, -email-inbox-star-reply,debug, -enter-date,original, -enter-password,original, -enter-text,original, -enter-text-2,original, -enter-text-dynamic,original, -enter-time,original, -find-greatest,hidden test, -find-midpoint,original, -find-word,original, -focus-text,original, -focus-text-2,original, -form-sequence,hidden test, -form-sequence-2,hidden test, -form-sequence-3,hidden test, -generate-number,hidden test, -grid-coordinate,original, -guess-number,original, -highlight-text,original, -highlight-text-2,original, -hot-cold,hidden test, -identify-shape,original, -login-user,original, -login-user-popup,additional, -multi-layouts,additional, -multi-orderings,additional, -navigate-tree,original, -number-checkboxes,original, -odd-or-even,hidden test, -order-food,hidden test, -phone-book,hidden test, -read-table,original, -read-table-2,original, -resize-textarea,original, -right-angle,original, -scroll-text,original, -scroll-text-2,original, -search-engine,original, -sign-agreement,hidden test, -simple-algebra,original, -simple-arithmetic,original, -social-media,original, -social-media-all,additional, -social-media-some,additional, -stock-market,hidden test,delay -terminal,original, -text-editor,original, -text-transform,original, -tic-tac-toe,original, -unicode-test,debug, -use-autocomplete,original,delay -use-autocomplete-nodelay,nodelay, -use-colorwheel,original, -use-colorwheel-2,original, -use-slider,original, -use-slider-2,original, -use-spinner,original, -visual-addition,original, diff --git a/src/agentlab/experiments/reproduce_study.py b/src/agentlab/experiments/reproduce_study.py index 93ef07fb..8a8a7093 100644 --- a/src/agentlab/experiments/reproduce_study.py +++ b/src/agentlab/experiments/reproduce_study.py @@ -11,7 +11,7 @@ if __name__ == "__main__": - # old_study = "2024-06-03_13-53-50_final_run_workarena_L1_llama3-70b" + # replace by your study name old_study = "2024-06-03_12-28-51_final_run_miniwob_llama3-70b" study = reproduce_study(RESULTS_DIR / old_study) diff --git a/src/agentlab/experiments/view_dep_graph.py b/src/agentlab/experiments/view_dep_graph.py index 0639507b..abbf7f87 100644 --- a/src/agentlab/experiments/view_dep_graph.py +++ b/src/agentlab/experiments/view_dep_graph.py @@ -1,3 +1,6 @@ +"""Dirty script to visualize the dependency graph of a benchmark, e.g. webarena, vsisualwebarena, +etc. You may have to detust it to make it work for you.""" + import math import bgym import matplotlib.pyplot as plt diff --git a/src/agentlab/utils/__init__.py b/src/agentlab/utils/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/agentlab/utils/bootstrap.py b/src/agentlab/utils/bootstrap.py deleted file mode 100644 index 666ba6cc..00000000 --- a/src/agentlab/utils/bootstrap.py +++ /dev/null @@ -1,120 +0,0 @@ -import warnings -from typing import Callable, List, Optional, Union - -import numpy as np -import pandas as pd - - -def stratified_bootstrap( - df: pd.DataFrame, - group_by: Union[str, List[str]], - strat: Union[str, List[str]], - metric: str, - func: Callable, - repeat: Optional[int] = 100, - rng: np.random.Generator = np.random.default_rng(), -) -> pd.DataFrame: - """ - Perform stratified bootstrapping on a DataFrame. - - Parameters: - df (pd.DataFrame): The input DataFrame. - group_by (Union[str, List[str]]): The column(s) by which to group the DataFrame. - strat (str): The column used to define strata within each group. - metric (str): The column containing the metric to which the function will be applied. - func (Callable): The function to apply to the metric within each stratum. - repeat (int, optional): Number of bootstrap iterations. Default is 100. - rng (np.random.Generator, optional): Random number generator. Default is NumPy's random generator. - - Returns: - pd.DataFrame: A DataFrame containing bootstrapped samples with applied function. - """ - if group_by is None: - group_by = [] - - if isinstance(group_by, str): - group_by = [group_by] - - if isinstance(strat, str): - strat = [strat] - - # extract subset of columns - df = df[group_by + strat + [metric]] - - group = df.groupby(group_by + strat) - - df_list = [] - for i in range(repeat): - new_df = group.sample(frac=1, replace=True, random_state=rng) - series = new_df.groupby(group_by)[metric].apply(func) - sub_df = series.to_frame().reset_index() - sub_df["bootstrap_index"] = i - df_list.append(sub_df) - - new_df = pd.concat(df_list) - return new_df - - -def bootstrap_all_benchmarks( - df: pd.DataFrame, - metric: str, - benchmark_cols, - group_by=["agent_model_name"], - repeat: int = 100, -): - """Add aggregated data as a new benchmark.""" - - # create a new df containing bootstrapped samples of iqm - df_bootstrap = [] - for benchmark in benchmark_cols: - # filter sub_df assuming that the benchmark column exists and is a boolean - sub_df = df[df[benchmark]] - - bs_df = stratified_bootstrap( - sub_df, - group_by=group_by, - strat=["task_name"], - metric=metric, - func=np.mean, - repeat=repeat, - ) - bs_df["benchmark"] = benchmark - df_bootstrap.append(bs_df) - df_bootstrap = pd.concat(df_bootstrap) - return df_bootstrap - - -def bootstrap_matrix(data: np.ndarray, n_bootstrap: int, reduce_fn=np.nanmean): - n_task, n_samples = data.shape - - indices = np.random.randint(0, n_samples, (n_bootstrap, n_task, n_samples)) - - assert indices.shape == (n_bootstrap, n_task, n_samples) - bootstrapped_samples = data[np.arange(n_task)[:, None], indices] - - with warnings.catch_warnings(): - # catches means of empty slices - warnings.simplefilter("ignore", category=RuntimeWarning) - results = [reduce_fn(b_data) for b_data in bootstrapped_samples] - - return results - - -def convert_df_to_array(grouped, metric="cum_reward", threshold=0.9): - max_samples_per_task = max(len(group) for _, group in grouped) - - arr = np.zeros((len(grouped), max_samples_per_task)) - - for task_idx, (group_id, group) in enumerate(grouped): - # Calculate the ratio of valid values - valid_ratio = len(group) / max_samples_per_task - # if valid_ratio < threshold: - # raise ValueError( - # f"Task {group_id} has insufficient data: ratio {valid_ratio} is below the threshold {threshold}" - # ) - - # Repeat the task data cyclically to fill up to max_samples_per_task - repeated_data = np.resize(group[metric].values, max_samples_per_task) - arr[task_idx, :] = repeated_data - - return arr diff --git a/tests/experiments/test_dask.py b/tests/experiments/test_dask.py deleted file mode 100644 index 39822634..00000000 --- a/tests/experiments/test_dask.py +++ /dev/null @@ -1,41 +0,0 @@ -from agentlab.experiments.graph_execution_dask import execute_task_graph, make_dask_client -from agentlab.experiments.exp_utils import MockedExpArgs - -TASK_TIME = 3 - - -def test_execute_task_graph(): - # Define a list of ExpArgs with dependencies - exp_args_list = [ - MockedExpArgs(exp_id="task1", depends_on=[]), - MockedExpArgs(exp_id="task2", depends_on=["task1"]), - MockedExpArgs(exp_id="task3", depends_on=["task1"]), - MockedExpArgs(exp_id="task4", depends_on=["task2", "task3"]), - ] - - with make_dask_client(n_worker=5): - results = execute_task_graph(exp_args_list) - - exp_args_list = [results[task_id] for task_id in ["task1", "task2", "task3", "task4"]] - - # Verify that all tasks were executed in the proper order - assert exp_args_list[0].start_time < exp_args_list[1].start_time - assert exp_args_list[0].start_time < exp_args_list[2].start_time - assert exp_args_list[1].end_time < exp_args_list[3].start_time - assert exp_args_list[2].end_time < exp_args_list[3].start_time - - # # Verify that parallel tasks (task2 and task3) started within a short time of each other - # parallel_start_diff = abs(exp_args_list[1].start_time - exp_args_list[2].start_time) - # print(f"parallel_start_diff: {parallel_start_diff}") - # assert parallel_start_diff < 1.5 # Allow for a small delay - - # Ensure that the entire task graph took the expected amount of time - total_time = exp_args_list[-1].end_time - exp_args_list[0].start_time - assert ( - total_time >= TASK_TIME * 3 - ) # Since the critical path involves at least 1.5 seconds of work - - -if __name__ == "__main__": - test_execute_task_graph() - # test_add_dependencies() diff --git a/tests/utils/test_bootstrap.py b/tests/utils/test_bootstrap.py deleted file mode 100644 index 41fe6b1f..00000000 --- a/tests/utils/test_bootstrap.py +++ /dev/null @@ -1,132 +0,0 @@ -import pandas as pd -import numpy as np -from agentlab.utils.bootstrap import stratified_bootstrap, bootstrap_matrix, convert_df_to_array - - -# Generate a DataFrame to use for all unit tests -df = pd.DataFrame( - { - "agent": ["A", "A", "A", "A", "B", "B", "B", "B"], - "episode": [1, 2, 1, 2, 1, 2, 1, 2], - "task": ["T1", "T1", "T2", "T2", "T1", "T1", "T2", "T2"], - "cum_reward": [10, 11, 12, 13, 14, 15, 16, 17], - } -) - - -df_no_var = pd.DataFrame( - { - "agent": ["A", "A", "A", "A", "B", "B", "B", "B"], - "episode": [1, 2, 1, 2, 1, 2, 1, 2], - "task": ["T1", "T1", "T2", "T2", "T1", "T1", "T2", "T2"], - "cum_reward": [10, 10, 12, 12, 14, 14, 16, 16], - } -) - - -def stratified_bootstrap_simple(df: pd.DataFrame, n_bootstrap_samples): - """ - Perform stratified bootstrap sampling to calculate mean cumulative rewards. - - Parameters: - df (DataFrame): DataFrame containing the columns 'task', 'episode', 'cum_reward'. - n_bootstrap_samples (int): Number of bootstrap samples to generate. - - Returns: - np.array: An array of overall bootstrap means. - """ - - # Initialize an empty list to store the overall means - overall_bootstrap_means = [] - - # Perform bootstrapping - for _ in range(n_bootstrap_samples): - bootstrap_sample_rows = [] - - # Stratified sampling for each task - for task in df["task"].unique(): - task_data = df[df["task"] == task] - - # Generate bootstrap sample for this task (sampling with replacement) - bootstrap_sample = task_data.sample(n=len(task_data), replace=True) - bootstrap_sample_rows.append(bootstrap_sample) - - # Concatenate all bootstrap samples to form the overall sample - overall_bootstrap_sample = pd.concat(bootstrap_sample_rows, ignore_index=True) - - # Compute the mean cum_reward for the overall sample - overall_bootstrap_mean = overall_bootstrap_sample["cum_reward"].mean() - - # Store this mean - overall_bootstrap_means.append(overall_bootstrap_mean) - - # Convert the list of overall means to a NumPy array - return np.array(overall_bootstrap_means) - - -# Test for expected number of rows in the output DataFrame -def test_with_no_var(): - df_bootstrap = stratified_bootstrap( - df_no_var, "agent", "task", "cum_reward", np.mean, repeat=10 - ) - df_mean = df_bootstrap.groupby(["agent"])["cum_reward"].mean() - df_mean_alt = df_no_var.groupby(["agent"])["cum_reward"].mean() - - pd.testing.assert_series_equal(df_mean, df_mean_alt, rtol=1e-1, atol=0) - - -# Test for statistical properties (mean, in this case) -def test_statistical_properties(): - df_bootstrap = stratified_bootstrap(df, "agent", "task", "cum_reward", np.mean, repeat=1000) - bs_mean = df_bootstrap.groupby(["agent"])["cum_reward"].mean() - bs_std = df_bootstrap.groupby(["agent"])["cum_reward"].std() - - # alternative method for stratified bootstrap - df_bs_alt = [] - for agent in ["A", "B"]: - bs_mean_alt = stratified_bootstrap_simple(df[df["agent"] == agent], 1000) - bs_mean_df = pd.DataFrame(bs_mean_alt, columns=["cum_reward"]) - bs_mean_df["agent"] = agent - bs_mean_df["bootstrap_index"] = np.arange(1000) - df_bs_alt.append(bs_mean_df) - - df_bs_alt = pd.concat(df_bs_alt, ignore_index=True) - bs_mean_alt = df_bs_alt.groupby(["agent"])["cum_reward"].mean() - bs_std_alt = df_bs_alt.groupby(["agent"])["cum_reward"].std() - - # high relative tolerance because of small sample size - pd.testing.assert_series_equal(bs_mean, bs_mean_alt, rtol=1e-1, atol=0) - pd.testing.assert_series_equal(bs_std, bs_std_alt, rtol=1e-1, atol=0) - - mean_alt = df.groupby(["agent"])["cum_reward"].mean() - pd.testing.assert_series_equal(bs_mean, mean_alt, rtol=1e-1, atol=0) - - -def test_statistical_properties_array(): - arr = convert_df_to_array(df.groupby("task")) - bootstrap_results = bootstrap_matrix(arr, 1000, np.mean) - bs_mean = np.mean(bootstrap_results) - original_mean = np.mean(arr) - assert np.isclose(bs_mean, original_mean, rtol=1e-1, atol=0) - - -# Test with no variation -def test_with_no_var_array(): - df_no_var = df.copy() - df_no_var["cum_reward"] = 10 # Setting a constant value for no variation - arr_no_var = convert_df_to_array(df_no_var.groupby("task")) - bootstrap_results = bootstrap_matrix(arr_no_var, 1000, np.mean) - bs_mean = np.mean(bootstrap_results) - assert np.isclose(bs_mean, 10, rtol=1e-1, atol=0) - - -def test_convert_df_to_array(): - df_uneven = df.drop(7) - result = convert_df_to_array(df_uneven.groupby("task"), threshold=0.7) - assert result.shape == (2, 4) # 2 tasks, 4 samples each - assert np.array_equal(result[1, :], [12, 13, 16, 12]) - - -if __name__ == "__main__": - test_with_no_var_array() - test_statistical_properties_array()