diff --git "a/app_playground.ipynb" "b/app_playground.ipynb" --- "a/app_playground.ipynb" +++ "b/app_playground.ipynb" @@ -4,11 +4,7 @@ "cell_type": "code", "id": "initial_id", "metadata": { - "collapsed": true, - "ExecuteTime": { - "end_time": "2025-04-28T11:49:33.800394Z", - "start_time": "2025-04-28T11:49:27.768470Z" - } + "collapsed": true }, "source": [ "from dotenv import load_dotenv\n", @@ -25,152 +21,37 @@ "# graph.invoke({\"messages\": [HumanMessage(content=question),]})" ], "outputs": [], - "execution_count": 1 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T11:24:12.828295Z", - "start_time": "2025-04-28T11:24:01.696627Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "from IPython.display import Image, display\n", "display(Image(graph.get_graph().draw_mermaid_png()))" ], "id": "da8311fc7f1acf6", - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOkAAAGwCAIAAADDo9U/AAAQAElEQVR4nOzdB1hT1/sH8JNBFiPsDYriVkDFhQscOIp7VG1ttdXW1ao4qh2OVmvVam1rtUPbau1QcVTtz133qBMBBygO9l4hAzL4v5j+KVq0QHKTe5L38/DwZNwwkm/Ofc85N+fyKyoqCEIU4hOE6ITZRbTC7CJaYXYRrTC7iFaYXUQrS8hublqZvFgjL9Gqy3RlSh1hPb4Nh8fn2Er5tg48Vx+hQMQlqO449I7v3o+XP0iAr1L/5rblKq2tA9/JQ6AupyC7NkJeaaH68ftNIyvU2DvxA1rbNW1rb+vII6jWqMxu8o3Sc/vzfQPFXgEieNVFtnS3WxnJygc35Xnp5U4eNl0HufJsOATVAmXZhargyLZsLpeEDXKVutoQy3LjdNH5/fk9hru16uJA0H+hKbuZD1T7vkkf8bafq7eAWK6/DhYoSjQRL7oT9FzUZLcwW338t+yRM32JFbh5oST9rjLyFQ+Cno2O7D68Kb96vHDE21YRXL3bl2S3L5UMn+FD0DNQ0MspLdKcjMm1quCCFh3tGwfZnt6dS9AzUJBdKBXGLWhArE9wD0ehiJt4VUZQTdie3UuHCzwbiAVCKx02atfb6eTOHIJqwurs6rQVV44WdBrgTKyVjZAb1N3xytFCgv6F1dm99mdR+EhrHyrq8oJLapKigoLpQlNjdXZvXij2bSohJnTv3r2oqChSd/Pnz9+/fz9hhkjCvR9fStCT2Jvd/Mxy2GM6OJv0aKFbt26Reqn3A2sjoJUdTBoT9CT2ZjctSdG8A1NTo1lZWdBS9unTJywsbNSoUXv37oUbN2zY8OGHH8JdoaGhv/zyC9xy6NChcePGde/evXfv3tHR0WlpafqH//bbb5GRkadOnYKfsGbNGtgeHrV06dLw8HDCABgsK85TE/Qk9h4DmZte5hMoJsxYsmSJRqP54osvHBwcLl68uGLFCh8fn9dee02hUJw4ceLnn38Wi8VxcXHvv//+lClT+vfvX1paum7dugULFmzbtg0ezufzVSrVjh07IOsBAQHjx48fOHDgvHnzYEvCABsRtzC7XCXX0X7UkXGxN7uKksrDGgkzkpOToUFt2bIlXB45cmSLFi28vb1FIpFQKORwOI6OjnB748aNIcSBgYE8XuWhiS+++CKks7i4WCqVQnYh5WPHjoVmG+4qKyuD7xKJBO4izJA48OUlGpGtJR/IUVfszS68VBLGsgtlwObNmyGIcCE4OLhVq1b/3sbW1ha6bmvXroVSAVpZaKfhxpKSkqqAtm7dmpiKrQNPUaJx8cLs/oO9+yAen8vjMTUlsXDhwhkzZly7du3NN9+EyvXrr7/WarVPbbNr167FixeHhIRAaQHl7zvvvPPUBnZ2dsRUoNtaocPjep/A3nZXIOaUFmucPBg5SNfGxmbMY4WFhfv27YNeGtQJcLX6NtBRg07Y1KlT9Vf17a65lOSrJQ74qYonsLfdtX1c4REGyGSygwcP6rPo5OT06quvQs2QmJj41GZqtVpf+OpBlOG7uQ67k0P1L8XsPoG92XX1EqpVTM0mwcDCsmXL7ty5k56efvjw4aSkpHbt2sHt9vb2+fn5sbGxmZmZUM5eunQpISEhIyNj+fLlnp6e5PE4rr5nVp3wMahA4A3ARPOs0xFnT4HYDrP7BPbWDN6NRad357bpZvyeOwQUioT169dDsQtRgxEGKAwGDRoEd8Eg14EDB2BcbMKECZMmTYLUwl3QaYOxCBhBy87OhkFcGGT498+E7bds2XL69GkYKoafT4wKJtVEthjcp7H62PPNHzwY944/tjdHf872ayZpHmrktwTtWD3W3bKTQ9pdJbF6Cpk2oJUtQU9i9doiQd0dd6xNadL2mUNRO3fu/Oqrr2q8C3paMJhQ411Q6Xbr1o0wA2aP/z3cpge7OJj4qPEu+Efc3NxqvCv2ZJGLp0Aoxhm1p7H982pQ8kpdbYJ7ONZ4L0zVwmRBjXfBYMKz6k5nZ2eYQiPMgE7es57S8vJygaDmyQUPDw/97N2/bZhzb8qqQC6Wu//C9uxq1OSPTelDplrpRw5jTxVzORVBz3jrWjm274n4NqRjf5eYz9OI9bkfJ89IVmBwn4WCKsorQNS8g/2hH7OINclJLTu3P2/ga14EPQM1a4ukJilvXSjp96pVLLeRlqS88EfeqFl+BA9heDZqeq9+TcUNW0l+W52iLrPwj27dulhy5VjBqNkY3P9A2Vp6eellJ3bkwpRbWJQrx+JGjR7clF84kN84yM6aPxpde1SuYXrtz0J4jUMjnX0Dxcx9tsJk5MWa+/HyzIeqcpUuLMrF2RMP0q0ViteOjjtbfC+2FFrilp0dKnTEVspzcBFU6CioKHh8rn7haHmJtjhPXZxX3qi1XbNQe8+GTI06WySKs6tXrtSl3VOWFKgVJVqdrgIyQYwqLi4uICDAuIfXVB5YUwFvNr6kcs1+kbsvNrT1QX12mTZx4sTo6Og2bdoQxDJ4nh9EK8wuohVmF9EKs4tohdlFtMLsIlphdhGtMLuIVphdRCvMLqIVZhfRCrOLaIXZRbTC7CJaYXYRrTC7iFaYXUQrzC6iFWYX0Qqzi2iF2UW0wuwiWmF2Ea0wu/9BKpU+a6F9ZF6Y3f9QXFyMy6+wE2YX0Qqzi2iF2UW0wuwiWmF2Ea0wu4hWmF1EK8wuohVmF9EKs4tohdlFtMLsIlphdhGtMLuIVphdRCs8N2DN+vXrJxKJuFxuVlaWo6OjQCCAy3D7nj17CGIHbHdrBsFNT0/XX87NzYXvPB5v+vTpBLEGl6CaDBw48KlbfHx8XnzxRYJYA7Nbs3Hjxvn6+lZdhUZ32LBhQqGQINbA7NbM3t6+etPr5+eHjS7bYHafacyYMRBZuAC9tKFDh0J3jSA2wew+k4ODQ//+/Tkcjr+//+jRowliGUsbZyjKVRdklpWpdMQYOrYYdrlRRlhYWHKsihAVMRiPx7F3tnHxFAjE2GoYynLGd+XF2uO/ZhflqX2b2JYbKbtGJ7bjZqeo+DbcxkGS4B6OBBnAQtpdWaHmj02ZXYd5OrrZEBqc25ut0xW3DZcSVF8Wsuf6dVVK3/E+tAQXdB3qkflAdetiCUH1ZQnZvX6iqHVXZ+oqyE4D3RLOl1SwtLqhgCVkNydVZefII7QRiLilRWqFTEtQvVhCdstVFbaO1FQL1Tl7iWSFaoLqxRL6auVKbYWOytES+MsJqi88jgzRCrOLaIXZRbTC7CJaYXYRrTC7iFaYXUQrzC6iFWYX0Qqzi2iF2UW0stLsDhoSXlpaWnXV3t6hY8ewya/P8PDwhKu792z/asOa40cvEcRi1tvuhvfsM3jwSLig1WrT01N//e3HmbMnfb9ph0QiIYgG1ptdd3fPtiGh+suh7Tu1aNH6zSkvnz5zvH+/QQTRAOvdvzVt0pzP50MD/NTtBQX5G79Zd/36ZZmsBOI+fNiYYUMrP+9+//691yeP+XT1hphdv9y8GQePjYiInD41Wr/kHjIBzO7fcnKyNRqNq6v7U7d/snJxVnbm0sWrHJ2c4+Ovr/70Iw93z7CwHjY2lUe7r//q0+hZ77ZuHXz12qV586e3aR0CpQhBJmG92a2oqICwwgWdTpeRkfbl+tXQY+vZo/dTm82atZDH5en7cD7evjtjfr5y7S/ILudx+xoRHtmmTQh5XHXANnfu3MTsmoz1ZhdSCF9VV/39G65c8YWjo9NTm3E5XOjGxd64WlRUCHGXy0sDAgKr7g1s3LTqsp2dfWmpjCBTsd7s9ukzYMTwsXCBw+FA7KBN/fc25eXls6PfEInF06ZG+/k1gAb4/Q+iq28geHJlSFyI25SsN7vOTi7Nm7V8/jY3b8VBsfv5Z98FBbXV31IiKyaIHbBT/DzQ7sJ3qfTvxZfi42Ozs7M4BLECZvd5oJyF8YQ9e7fn5+f9dek8TLZ1CO2ckvIQal+CzA2z+zwuLq7z5i76669zL40f8suvPyx4Z+mIEeMyMtPmzp9GkLlZwjqQuz5PC45w8WggJrQ5uDmtx3BXz4YiguoO5yYQrTC7iFaYXUQrzC6iFWYX0Qqzi2iF2UW0wuwiWmF2Ea0wu4hWmF1EK8wuohVmF9HKErLr4GpD6cFwYnuejQAPQ60nS3jiJPb8vDQjnGTdxOD99ui23MVbQFC9WEJ2A4PtcinMblqivGVnPBd2/VlCdj0aCBu0kJzbm03okZ9Rdv1Efq/RbgTVlyV8bkIv7kzxo9sKV1+Rq4+Yy9azC3O5pCinvEyhvR8vGx3tx7fBD27Wn+VkF2SnlCXfKFXINEW5RjtJb15uroNUKhAYpyq1c7KxseF4NBC1DnMgyDAWlV0mTJw4MTo6uk2bNgSxDI7vIlphdhGtMLuIVphdRCvMLqIVZhfRCrOLaIXZRbTC7CJaYXYRrTC7iFaYXUQrzC6iFWYX0Qqzi2iF2UW0wuwiWmF2Ea0wu4hWmF1EK8wuohVmF9EKs4tohdn9Dx4eHhwOrl7DRpjd/5CdnY3Lr7ATZhfRCrOLaIXZRbTC7CJaYXYRrTC7iFaYXUQrzC6iFWYX0Qqzi2iF2UW0wuwiWmF2Ea0wu4hWmF1EKzw3YM0iIyP5fD6HwykoKLC3t7exsYEbJRLJzp07CWIHbHdrZmdnl5KSor8M8dVfmDx5MkGsYQnncWdCREQEj/fEGbX9/f1Hjx5NEGtgdms2atQoX1/fqqtQPEAV4eTkRBBrYHZr5unp2bNnz6pPWUKjO3bsWILYBLP7TC+++CJEVn+5b9++UqmUIDbB7D6Th4dHeHg4NL1+fn5jxowhiGUsYZwhN7VMpdQSBoR3GnHxxN3u3bvLcgSyHAUxNi6X4+QhkNjzCKo7usd3T+7MTThf7NtUotVQ+V84ONuk3Ja7+Yk6RDp5BYgIqgtas1uhI3s3pDds4xAYYk8opyrVHvs5I2KUu2eAkKBaozW7e75Kb9bBya+ZhFiK3zek9H/V09VbQFDtUNlXS74hd3QTWlJwQffhnleOFhJUa1RmNydNJRBbWv9G6mrzIKGUoFqjMrsquU7qbmn7Vh6f4+EvlhVqCKodKsfIypQ6rVpHLE5xXjkul1p7eBwZohVmF9EKs4tohdlFtMLsIlphdhGtMLuIVphdRCvMLqIVZhfRCrOLaGVdn1fTaDTDR0ZG9A5NTX1EEOWsK7uXL1+Qy0u9vX2PHP2DMOn+/XtjxkURxCTryu6hw/s7dgjr07v/0WP/Y/QDI4lJtwhimBVlt0RWcuHimYiIyMjIqOzsrNgbV6vf+/u+GGgp+w0Ii54zJSXlIdQVJ08d0991+3bC3HnTBg/tFTW45weL5sJj9bcvWjxv6YcL9u3f9fIrwwZGdZ8ydfyt2wlw++bvN6xa/SFsBj/k2PFDBDHDirJ7/PghoVDYNaynj7dv69bBR478UzZcj72y7vNPunWN+O6bX/pFRi39aAHcyOdXdmQzMtPnzJvKt7H58vPNa9d8UyIrnjt/FcdJ0QAAEABJREFUmlqthrsEAsGNuGuJibe+2bhtd8xRe3uHVauXwu0vjXtt+PAx7u4ee3cf69mjN0HMsKLsHj68P7xnX4gvXI7s+8LpM8dVKpX+rqNH/+fq6jZt6mx//4b9+kV17xZR9ajff9/J4/Hee3dZgwYBTZs0X/jOh2lpKWfOnqi8j8MpK1O9NWOera2tSCTq1avfo0cP4GfCZaFAyOFwpFJH/eKniAnWkt2HD+8nJt2GyOqvRoRHwpjD2XMn9VezsjKaNGnO5f79bHTs2LXqgbfvJLRo3tre7u9P0nt6ekGznZycpL/q6+MPSdVfhnYXvstkJQSZhLWM70IvDb6/PWtS9RuPHDkA/TZSWQoXu7i6Vd3u7uZRdVmhkCck3Ijs36XqFigY8gvy9JcFwqdXVMC1uE3GKrKr1WqPHT84YvhYqAeqboQ69bN1K/Lz81xcXG1sBJrHJaxeaams6rKdnX1wULvZsxZW/4ESiS1B5mYVNcPlKxcho4MHjWgS2KzqC/pkErEEMg0beHv53L17p2r7v8vZx5o3a5WekQpDwlAK67+gkHV2diHI3Kwiu9BLa9QoEGJX/UboRXUJ66GfpOjRo3d6RtqWrd/BqAKMap2/cLpqsyFDRkEz/MmqJXfvJUIvDbaZ+PropGpBrxG01gUF+fHxsfCeIYgZlp9dKBggiz261zBW1bN7b5gAg1DCSNaEV9/cs3f7pMljjv95KHr2u6Qy3JVLQHh5en+29tvCgvy3Z74+Zdr4y1cufLx8XfNmLZ//S3v36u/l5RM9d0pVdxAZHZXrkR3aku3VWNKojdFW0YMnAZpJKHz1V+Pirs+cPXnLDzFPNdVMi1n7cNRsXztHPECqVnDt6ErXrl8eObr/T9s2p6WnwqjCho1rW7Zs4+fXgCAWw7d4pfbtOi6Yv2T7zp9+/uV7KFVDgttPeXMWB9eoYTfM7t9g+Kz6CBpiP8wuohVmF9EKs4tohdlFtMLsIlphdhGtMLuIVphdRCvMLqIVZhfRisrs2jnyuDwLPNhA6s7n8fDoqNqi8pmydeDnpqqIZVGUaPIylMtXLtJo8BRrtUJldv2aSRQyS3uBc1JVLTs6de3a9fTp0wTVApXZdfUWeAeIzu7JJpaiMLv8yuG8bkNcBwwY0KtXL7hl2LBh586dI+jZaD2PO7h5vuTujdKA1vbO3iIbIZXlL5fDKcwuKy3SxJ8teOW9BtWLeJlMtmXLlhkzZuTl5bm6uhL0LxRn9+TJkzcuprbwjYTXvihX/Z/b63S68vLyqqVA6ketLufz+RyOcfZXrt5Cna7Cr6m4fW+nZ21z8ODB8+fPL168WL/GFKpC69MBHZoDBw58+umntdlYoVD8+OOPJ06cePDgwfz580ePHk3qa8WKFU2aNBk5ciQxFagioH25du1ax44dCaqGvna3sLDw5s2bXbp04fF4tdl+7969O3fuTElJUSqVdnZ2S5cu7dmzJ6mvtLS0oqKi1q1bE3OIjIxcvnx5hw4dCKKur1ZQUDBq1Kjg4ODaBPfMmTOTJk364osvEhMTIbhwi1gsdnd3Jwbw9fU1V3ABvAlv3LgBF3JycojVoym7+fn5xcXFx44ds7ev1afboYm6fv16Sck/i9tByWh4v2fu3LnETKRSKbwb4QKMoy1atEir1RIrRkd2S0tLhw4dKhAIAgICav8ooVBY/bO+UB1xuVw3NzdimOzs7Fu3zLysORTcnTp1gv2JNU9k0FHv7tmzB4o82F+TuoPR/rKyMvJ4nKFdu3abNm0ihnn48KFEIjGw9jAWtVoNnTnos4aEhBArw/Z2d9myZeTxQH39ggtdK2ho/f394S0KbbDhjS5o2LAhS4JLHq+qFhMTEx8fTypXEc4i1oTV7S4Et3Pnzn369CH1NXbsWBhYaNq0KXncABtlpgreD9B4L1myhLDM1q1b79+/D3Vw1SLYlo2l2T179my3bt2gzIVRLVJf3333HfRmpkyZQowNak14G7BwsgDGvIOCglxcXGxtLX+FYDa+QVeuXJmamkoqVwKtf3ChBTpy5AgTwSWPx6rY2UmKiorSF0iws4JRcGLR2JVdmLsnj3fusK8nhoH5s1WrVhFmQD4MnFtmFLzn4d11+/ZtYtFFMItqhp9++gkCAVMPxGAbN26ETox+KJQJML0Mw2TTp08nrPfVV19BiwBFsOUtDciWdhdmEGDqwSjBhVFP/YwaYYyfnx8tR9nCG6xt27YwkQ5T2cSymL/djYuLg+BC78dYpyIbMmQINDb1G1OrPZiVZc9IWW1A0/DSSy/BDLl+1MUCmLndhfGmzz77DApcYwUXXpvhw4czHVxAV3ABDD5s27YtKanyzHAZGRmEfuZsd6G5LSgogKF+YiQJCQmrV6/esmULYd769eu9vLxGjBhBKATPklKphCKY0Mw87S40t6GhoWKx2IjBJQyPLTwF/nKodgid5s2bFxwcXF5eTvXxaOZpd/ft2zd48GBiVGvWrIGGcNy4ccQk4HmDIV7aTxcMxcNrr70GwzJ1OsiJJUza7qrVav0BhEYP7vXr12E402TBJZXnweZYwNSrt7c3DE3eu3ePPN4ZEqqY9NlfsGDB5MmTCQNMWS1UeeONN2JjYwnl3Nzc+vbtCxc2bdq0YsUKQg8TZXf//spTUcNuvVmzZsTYPvnkE4iRs7MzMa2QkJC7d+8SS7FkyZI2bdoQehpgU2QXpgmcnJwIMy5duvTo0SOjTGrU1VtvvWWW38ucqKjKMx1BHT9gwAD2J5jZvhqkqkGDBlBOBQYGEmaEh4cfOHDAkKN26k2r1cpkMkdHR2JxYPwBRoK7deuWkpLi7+9PWInBdhd25ZBduMBccD/66KNZs2aZJbiAx+NBQ6VSWdrKaOTxzAsEFy5s2LChlgsJmB5T2c3KymrcuHGPHj0IY65evQqd/aFDhxLzgd/+8OFDYrmgATLj56Kfj6maAWompg/Nnjp16sSJE3HFDabBSwnTnyycA2eq3c3Ozv76668JY27evCmXy80e3Ly8PJidIhYNOm3QTBD2YSq7Pj4+hn8i9zl++OEHaHSJucHkamJiIrFosP9k54FHDPbVvvnmG+iGEwZAifngwYOIiAhibq6urrRPC/8nX19fmDQm7EPlOpAwih4aGqofjERMs7p6F1y4cOHXX38lxgYl5sWLF1kSXKx3zYjB7MJcGswaEGODSnfChAmEHbDeNSMGh7GaN28OLy0xKqVS+fvvv589e5awA9a7ZkRZvQvTPEKh8PXXXyfIVKyx3gXff//9sWPHiPGwZGisCsz7Y71rLsxm18XF5fz588RItmzZMn78eFYd8f3OO+9gvWsuzE7bDhgwwIgLzEOjqz8OmD3gRRUIBMSiYb1rqJiYmLt37y5cuJAg07LSehfMnj3bKHvVH3/8kVWVrh7Wu2bEeHY9PDwM/yz4oUOHQkJCPD09CctgvWtGjK8gGx0dbfhyn1DpLl++nLAP1rtmxHh24aUdMWKETqcrLi6GmYWrV6+SOjpz5oyXlxdzH74wxMqVK4mFggotMzOTw+HoV6J4fDZPjlqtNu6gpyGYyi5MH8THx2u12upLZ0IrBfVDUFAQqQtodGfOnElYCepdR0dHi2x6w8PDobl9ap/JqrKNqXp38+bN/v7+T635Cq9xXYN77do1Ho8XHBxMWMmC691/L0kIDXDbtm0JazDYV5s+fXr1E/HBf16PCLJtIu0pFlzv2tvbR0VFVf/glimXzKoNBrMbERExaNCgqpN2CIXCLl261OUHVK4CnZ+fHxYWRtgK6l0mVkthiepNLzQ9sM9s0aIFYQ1mx8ig6W3fvr3+MrTBLVu2rMuj2d7oEksf33VwcHjhhRf0TS80uoafBMS4GB/f/fjjj2GIAN61zs7ODRo0qP0DYUj89u3b+qWyWMvix3dHjRqlX1sEGl39ik/sUYtxhgqiVlcoSuo9Rsub8/YHkOCQVmHFeeraP2zr5pjxY96s5UNgYtvRzQzH0Zqr3pUXaTUaHTEFYb9ew/bL948YPL5OL58hJPZ8GwGH/Ne5Xf7jeIabF0punC4qLdIIxTxiWjqdlsut7S91cBWk35UHtLbrEOnk7ickluv0nrzEKyVuPiKTJcn0lHKNo6sgqIe0ZSeH52z2vOxePlyYn60O7uls58i6EzjWCF7O0zFZ4aPcvBuZ6ORnphzf1WnJjs9SW3Zx8m4kFkpM3ZSYGDSXsScK3H0F7fs8c7m3Z9a7fx0sKCrQdB3iTktwgdTVZtAUv1O7cjOSTbRGmCnrXQhuu96usG+x+OACSF23Ye4F2eWXDhc8a5uas1uYo87LLO880AhnPTe93mO9rx4vJCZhsno34XxJg5Z2Xo3ExJp0jnLPSS0vzqu5r1Vzm5qbRvHahmJ7XtZDpUqhE0kYH0Ux2fEM6feUno0kxCpBGqWuNSz1WfOrKyvSuvtS/Bb3a25bmG2KYVeTje9Csevkwd4zGDPHzU8kK6i5V1pzdjVlujKVllAL/lvTfB7EZPVucX65TmeaQTF2KVfq1OU1v5TU9MPYyRqO32UtzK5BLPj4Xfaj/gxh5pWZmVlWVkaQOWB2DfLuu+/qzy6NTA9rBoN4eXkJhZY8Bc1mmF2DfPzxxwSZCdYMBsF614wwuwbBeteMsGYwCNa7ZoTZNQjWu2aENYNBsN41IxZld/GS+XPmsnHNtudgf72r0WiGj4yM6B2amvqIWBajZXf3nu2frFpCrAz7693Lly/I5aXe3r5Hjv5BLIvRspuYdItYH6h3mzZtSljs0OH9HTuE9end/+ix/9F4Lr3nME5f7a2Zryck3IALhw8f+Pabn5sENouPj/1u8/qkpNscDqdF89aTJ81o0eLv04H/8b+9O3Zuy8hIk0hsO3boMuXNWS4urk/9wP0Hdsfs+iU7O1MoFIUEt39rxjxXVzZ+iAPqXWdnZ9Y2vSWykgsXzyx4Z2mzZi23/rQp9sbVtiGh+rsWLZ7H4/Hatu0Ar0VBQZ6/X8O3336n5ePXKDs7a8PGtTfirimVCi8vn1EjX3ph4NDlKz4oLipctXK9/uGvTBihUMhjdhzSX4V6T6PVLP9obX5+3tffrIuLv15cXNSoUZM3Jr0VElK5QEdy8t1Jb4z9eNlnX3/7eY/uvV5/bRoxmHHa3RXLP2/apHmviMi9u481CgiE0mru/Gke7p7fbNy28auttrZ2c+ZNzc3NIY/DvWbt8gH9B2/5cdeyD9ck3b3z7nuznmoPbty4tvazj0ePennzpu2ffPx5cUnRh8tYutw5y+vd48cPwfuqa1hPH2/f1q2Djxz5p2wQCASQzsTEW/Aa7Y45am/vsGr1Uv1dK1ctKSwq+GTFF99v3jFs6IufrVtx7frl0Hadbt6K02orj+ouKMjPzc1Wq9XpGWn6h0BY27frBPfOXzDj1u2E9xYu2/Ttr82bt3pn4VuPHj2ADfRn8tr603fjxkwYFDWCGINxsmtnZ6NGcI8AABAASURBVMfj820EAqnUEd7Ne/fthLy+M39JgwYBDRs2gvc9/Fewz4Itd+76uVvX8DEvvuLt5dOmTciM6XMhvrdvJ1T/aQ8f3ReJRP0io+AZh9Z60fsrpk2NJqzE8nr38OH94T376v/CyL4vnD5zXKX6/09zcThlZSrYodna2sKz3atXPwiZ/t4HD5M7dezavFlLeP6HDB755RffQ3sELbRCoUi+fxc2gPa7SZPmsHdNiI+FqykpD4uKCkPbd7p06fz9+/fmznk/KKitr6//jGlz3Nw8du/5Dbbh8io/Hxoc3L5fvyh3dw9iDIyMM9y9ewd2UlXLsMGzA7uk5OQk6PPC/wYNQNWWUE7A93vJTzRd+v3a27MmQXWRk5Pt7OwCzyNhJTbXuw8f3k9Mug2R1V+NCI+E5//suZNVG/j6+ENq9Zeh3YXvMlkJfO/Sufu2nzdv/HpdbOxVeEiL5q0cHZ0gcBBHfVjj4q7BC9emTVtobuEqtN9wr79/wzuJN6F9hRpP/zO5XG5wULu79/75XElV3WgUjMxNQCXk7vbEe0sskSiUCqVKCeWBWPzPZwbF4spPxUFdVX1jeBbWf/HD9p0/ffvdl5+uWaZvnqEmIezD5noXemnkcRNQ/cYjRw5Av01/WfCvP1tfvM2etTCwcVPYT0IpDJkeNnT0K+Mnw+60fbuO8Qmxw4ePgXYXClmhSLTu84PkcXahYIALpfJSKCT6Dfhn7UPY37q5/bPeP+yNifEwkl34E+HfqH4LDNNA+SsWieG9KK92l1whJzX9S40bN3l3wYc6nQ66gFDdL1j49vZf/2Dh2U+h3o2OjmbbQl3kcWiOHT84YvhY2EdX3QjVLRSv0J36d+e4OnieIaDwBZXAwUP7Nn+/QergCFehbPhy/Wq4EYqE1m1C+Dx+ZmZ6YWFBQkLs5ElvwQPt7eyhIYcCuvpP01cLTGCkZmjWtCU8TVVLZstKZfDf6qsIeEPfvPnPqVNuPb7c7MmS4NateP02EHSonCZOmAJPEPQPCPuwtt69fOUiZHTwoBFQlVZ9QRdCIpZApp/zQHixjh47qH/toFQYO+ZV6HLp9/shIaHwKhw+ciAgoLGDvYNEImncqAkMG8O4BDTJsEHzZq30FTPsOfVf0AVyc2XqPCtGyy685+7dS4R/EgZHBg8eCWXA6jUfwYADFLjLlr9nZ2fft89AUrmu4Mvnzp/aGfNzVlbm9dgrX371abu2HeBprf6j/rp07v1Fc06eOgbdWOjJ7dsX4+XpbawC37hYW+9CL61Ro0BIT/UboUHtEtbjPycp1n2+4tO1y+CZz8hMP/7nYeioBAe3g9ulDlJ4paDvFdTm79XPofXds3c73Agph6uhoZ2hbVr+8ftQKGdmZRw7fuiNN8btP7CLMMNoNcOwYWNWfLLo7ZmvL12yGkZtV6/86ttNX8KQHtRJQUHt1q39FoYgYDMotqB7C4UU1LJQKsCYA4zvPvWjxr88Cd73MEwILQeEvnWrYBiveWr5f5ZgZ70Lz975C6fHja1h6eKe3XsfPfq/6v2np0Ab9OmqDd9tWh895034OZ6e3q9NnNq/3yD9vVA2bN/xE7yg+qvw0uze/RsMZeivwn4VBoA3frNu8dL5KpUSHvvqq2+MHMHUUuk1r6X318ECtZoE93QmdDr0Q1rXwS7ezK+ANHHiRNPUu799mtp5kLuLp9Udbxl7okAoIh371xBFPAbSIHj8rhlhdg2Cx++aER6/a5C0tLR/ZqqQaWF2DfLBBx/cvXuXIHPAmsEgvr6+VdOqyMQwuwb56KOPCDITrBkMgvWuGWF2DYL1rhlhzWAQrHfNCLNrEKx3zQhrBoNgvWtGmF2DYL1rRlgzGATrXTOqObsCEYfDo7hJdnARcE3y95us3nVyE/BYeRQo0wRinuAZjUPNLzC89tkPFYRaDxJkLp6mOP2OyepdnoCTl2GNhXXWA4XUpeYWtubsevhTfFyfrEDt38zWRmiKVspk9a5voLi0WEOsD7yKng1qPg675uzaOfIbtJCc3J5FKHRka3qXKBdiEiard5t3sC/IVCVeLiHW5MRvmY3aSMT2NaeU85w1qu5el8efKwrq4ezoLhSK2V7+lhZpZAXlp2KyXpzj7+BsmX3Q/32f5eIt8mggdvYSWnD1W6bQFeWU3ziVH9zDMTDE9lmbcZ6/vlpqkjL2ZFFOqkqlYPUpWl08hWVKbYMWtp0HOotsmfpQ9b9Bvevq6mrKoYbrJ4qSrsm4XE6OCc9XDiEx5ecFBSKuZ0Nx23BH3ybP+9QWp5ZrA7L8XLYVOsIzR1Nrss+rPa2C6Ey1puOjR4/mzZu3Y8cOYirc2u3ja/uCc1leMpjpzzPb+C6HcE3VDnIq2zctCwOAcxMGweMZzAjnhA2CxzOYEWbXIHg8gxlhzWAQf39/PJ7BXDC7Blm6dClBZoI1g0FSUlKw3jUXzK5BFi9ejPWuuWDNYBCsd80Is2sQrHfNCGsGg2C9a0aYXYNgvWtGWDMYBOtdM8LsGgTrXTPCmsEgWO+aEWbXIFjvmhHWDAbBeteMMLsGwXrXjLBmMAjWu2aE2TUI1rtmhDWDQbDeNSPMrkGw3jUjrBkMgvWuGWF2DbJ58+bk5GRi0bhcbmBgIGGf2q4tgp4lJiamf//+dnZ2xBKVlJQMGTLkxIkThH0wu0ZQWlpqqdnt3Lnz2bNn+Xw29ouwZjAC2Kt2796dWJyBAwf+/vvv7AwuwewahUQiOXTo0B9//EEsyMsvv7xmzRoPDw/CVlgzGI1Go5HJZE5OToR+M2fOHDVqVLdu3QiLYbtrNLBvjYuLi46OJpSDQevevXuzPLgE212je/ToUXFxcVBQEKHT+vXrod85YcIEwnqYXeOD7HI4HAcHB0KbX375JTMzc86cOYQGWDMYn1Qq3bBhw86dOwlVoLt569YtWoJLsN1lTnx8PHTS3d3dCQ0uXbr0ww8/bNy4kdADs8ug1NRUNzc39h9odu/evffee2/79u2EKlgzMMjPz2/s2LEpKSmExQoLC6dMmUJdcAm2uyYAu+N27dqxdnYqNDT08uXLHApPeYXtLuM6dOhw8+ZNwkr9+vWDLhqNwSWYXROAZHh5eQ0YMICwDNQzX375paurK6ET1gwmolQqofBt1qwZYYcZM2a8/PLLnTt3JtTCdtdExGIxDJnduXOn6paBAwcuWrSImMSKFSv69+9fdfWDDz6A3051cAlm15QcHR0TExM//PBDuBwVFZWTkwNzAcQkbty4Ab8OfilcXrduHTT/kF1COcyuSQ0ZMmTatGl9+/bNysqCqzKZDFJFGAbDt/CLuFwu/NLu3btD/Q3VAqEfZtfUxo0bB0Oq+st5eXlXr14lDLt+/Tr8Iv1lKLv37dtHLAJm16QiIiIKCgqqrkITCGOrhGFnzpzRarVVV4uLi3v06EHoh9k1nfHjxwsEgqcGdtLT06ESJYyRy+XwK6rfAn8ATFOPHDmSUA7XFjGdn376CarbgwcPwkwb5BV239DuQisI+3SYIyDMgN+oL1EgskKh0M3NrX379tBRg+k0QjnMrinodEQ/cxXUJhi+oC38888/Dx8+/OjRo8zMzMuXrkT2ZSq7Fy/8VVIsc3f38PHxgXGGnj17SqVSuL1C9/cGHGp3vTg3wYjUJOWDeEVWilIh06pKNWIHG1l++TO2heef6SnZZ/4KiQO/TKkV2/LF9jzPBqKGLSUNWkgIJTC7xqQs1f51uOjWhSI7Z5Gdq63Q1oYv5NkIeVw+exs3nbZCU6ZRq7TlSk1pXmlJjrJlF8fQPo72TmzfJ2N2jeZkTF7ilRLP5m72rmIuj8qjW0hlWUxkuYrspPyAVra9x7ixuaLA7BpBTrrm8JYssZPEtaGUWIr81BJ5nrzXaHffQAFhJcyuoR7dURzdltOosy+9be1zPLiU3jXKuWl7Nq5YheO7Bsl6WHZ6b2FgVz+LDC4I6Ojz19HilCQlYR/Mbv3lpKkObc32C/YkFg3+wVO78lOTFIRlMLv1BKXWjjVpDTv4ECvgF+L1x+YslUJH2ATr3Xo68F0WEdnZuYqJdVAWlSnyCke8xaL3Kra79ZGRrCzM1VhPcIHYUVim4jxIkBPWwOzWx6ndeS4BzsTKwL98ek8eYQ3Mbp3lpJapyzkSRyFhpZKSvLkfdEq4fYoYG0wT8gT8NNaMOWB26yw5rlQktaJqoTqxVHL3RilhB8xunSXHyR3cqTlgxbjs3SXsKXnxGMi6KVdWcDgckT1T06Swx99/+IsHj2LliiIvjyYDI6cFBrSH289c2H781A+vjv1k7x+f5Rek2koc+4S/1qFdlP5RFy7tPn76x1J5oZ9Py3693iCMEYj5IjsbWYHG3tn8ycHs1o1cpilTMjXMqdVqv9s6s1ytGjdyqb2dy7m/dm7aOmv21K0e7gF8vkCplB09+f2EcSulDu5HT2yK2beiSeOOjlL3+w+v79q/smfXl7p0GJ5fkLb/0BeESeoynULGiuxizVA38mKNjYhHmJF490Jm9r1RQ95t1LCtm6v/4AGzHaUeZy/ugLu4HK5Wp+kb/pqToyeXyw1t+4JWq8nIqjwN99XYgxD0gX2nu7r4NmvSuXOHoYRJfCFPXqwlLIDtbt2UKXQie6ZGGFLTb/F4No0D2umvQkYhxOmZSVUbQBWhvyARVy6qrlLJ4Ht27kM/35Y83t/vKHgIYZLQVlhexooJNsxu3QjEXFVpOWGGUlWq1aoXLP3nVG06nRYqhKqrNjZPvG30c6JlZXIn6T9nkhIKmO1HlsnL+QJWjA9iduvG1oGnUWkIM8Rie4GNaNbULdVv5HL/o0QRCMRl6n/GXJWPG2PmaMo1tg6siA1mt24kTL5sMEoAHTVoSz3cGupvKSjMgFr2+Y9yc/FPSv4L2mD9UqT37jO74AOn8g3MithgX61uRJLKdrBMriYMaBbYyduz6a8xi+89uAqpvRZ3eO2G8Rcu737+o9oG9yuR5cHwAvTz4hL+vHL9IGGMplxbptA4uGC7S6dGbWyzMxVCW+N/vIfH409+9fMDh77Y+tvC8nKls6N3ZMSkHmFjn/8oSPyg/jNPnfsZxtR8vZuPHvruZxtfgVEIwoCSHEVAK1vCDngMZJ1l3Fcd+y3Pv60XsT7p8dlhL0hZEl+sGerMu5HIhk/KFUz12FhLW67TlKnZ0+5izVAfnQY4XTyc792q5nOcw/568Sc1r3Oj0ZTzeYIaF/rw8gicPukbYjyLVkTCEFuNd1V17J7i5Og1Z/o28gy59/M7RrLoTN9YM9TTr6tTpX4uEmkNI53wlBYWZdb4KFWZXGAjhkmHf98FsxJSBzdiPAWFmY9XxKmBWl1uY1PDIRnQD3WU1vyGhO5p1u3sVz9oQFgDs1tPsgLNri8zGna0is+rgdTrGQNe9XD1YdFaDVjv1pO9M7/HCBfouxArkHk7N7SPlFXBJZhdQzRqbduhjzQtnsHVc9kg/WafWHr2AAABCUlEQVRumy62LTqy7rT0mF2DNG1nGxxmm3I9k1iotLjsJm2ErbvYE/bBetcIUhIVp3YXOHg5SD3YMn5kOFmusiS7pFOkQ2AwGxd0IphdY1GW6o78nF2Yo3EPdGHtxzBrSVlSnpucb+vAjRznZu9sQ9gKs2tMOSll104UpdxR2LlKHDzs9OvvUnCy3gqiLtPCbEtxdqk8X+4TKAnp4eDdmO2fJ8XsGp9Cpn2QIH94S5H1SKUq1fBsuHZOQhUzh+8YSCDmQyurLteJbHneAWK/puKA1rZ2jnTMWGF2GadS6MrkWsLW1lco5kJwCYUwu4hWeDwDohVmF9EKs4tohdlFtMLsIlphdhGt/g8AAP//54bcEgAAAAZJREFUAwCxsMQId78m+QAAAABJRU5ErkJggg==", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "execution_count": 2 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T20:03:01.129619Z", - "start_time": "2025-04-27T20:02:54.875475Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "res = graph.invoke({\"messages\": [HumanMessage(content=\"How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia.\"),]})", "id": "a9fdfecc1af0975e", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "-------------------- Starting to create a plan --------------------\n", - "\n", - "The plan is: 1. Access the English Wikipedia (2022 version if possible).\n", - "2. Search for \"Mercedes Sosa discography\".\n", - "3. Identify the \"Studio albums\" section.\n", - "4. Filter the albums listed to include only those released between 2000 and 2009 (inclusive).\n", - "5. Count the number of albums that meet the criteria.\n", - "6. Provide the count as the answer.\n", - "\n", - "-------------------- Agent has been called -----------------------------------\n", - "\n", - "\n", - "The Prompt is: messages=[SystemMessage(content='# Task: Answering GAIA Benchmark Questions\\nYou are tasked with answering questions from the GAIA benchmark for AI agents.\\n\\nProvide ONLY the precise answer to the question. Do not include explanations, reasoning, or any additional text. Be direct, specific, and concise to meet the strict exact-matching requirements of the GAIA benchmark.\\n\\n# Output Format\\n- **Single-word or short-phrase answers:** If the question necessitates a brief answer, provide just that word or phrase.\\n- **Numerical values:** Provide only the number when applicable, with no additional formatting or units unless specifically requested.\\n- **Full sentences:** If the question expects a sentence, provide the exact sentence required with no extra characters, punctuation, or formatting.\\n\\n# Notes\\n- Be aware of strict exact-matching requirements; even minor deviations can result in an incorrect response.\\n- If any ambiguity exists in the phrasing of the input, respond with an answer that aligns with the GAIA benchmark\\'s intended interpretation.\"\"\"), (\"user\", question)])\\n', additional_kwargs={}, response_metadata={}), HumanMessage(content='How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia.', additional_kwargs={}, response_metadata={}, id='68e50b88-39ef-4456-a26d-736685236c92'), HumanMessage(content='Write a plan how to solve this qustion?', additional_kwargs={}, response_metadata={}, id='a851377d-2099-4c11-b2b9-35ce01592bdc'), AIMessage(content='1. Access the English Wikipedia (2022 version if possible).\\n2. Search for \"Mercedes Sosa discography\".\\n3. Identify the \"Studio albums\" section.\\n4. Filter the albums listed to include only those released between 2000 and 2009 (inclusive).\\n5. Count the number of albums that meet the criteria.\\n6. Provide the count as the answer.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-918a04ec-90ff-48b1-a056-be00c1fdb3c4-0', usage_metadata={'input_tokens': 259, 'output_tokens': 87, 'total_tokens': 346, 'input_token_details': {'cache_read': 0}}), HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={})] \n", - "\n", - "Agent has made a decision:\n", - " content='' additional_kwargs={'function_call': {'name': 'retrieve', 'arguments': '{\"query\": \"Mercedes Sosa discography\"}'}} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-21ed6b3d-23db-4acc-88c4-4800f901a701-0' tool_calls=[{'name': 'retrieve', 'args': {'query': 'Mercedes Sosa discography'}, 'id': '8d0e5e80-a569-4cbd-808e-220f4dd59953', 'type': 'tool_call'}] usage_metadata={'input_tokens': 389, 'output_tokens': 5, 'total_tokens': 394, 'input_token_details': {'cache_read': 0}} [{'name': 'retrieve', 'args': {'query': 'Mercedes Sosa discography'}, 'id': '8d0e5e80-a569-4cbd-808e-220f4dd59953', 'type': 'tool_call'}]\n", - "Type von der Antwort: \n", - "\n", - "-------------------- Decision of forwarding has been made --------------------\n", - "\n", - "This is round: 2\n", - "The last message is: content='' additional_kwargs={'function_call': {'name': 'retrieve', 'arguments': '{\"query\": \"Mercedes Sosa discography\"}'}} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-21ed6b3d-23db-4acc-88c4-4800f901a701-0' tool_calls=[{'name': 'retrieve', 'args': {'query': 'Mercedes Sosa discography'}, 'id': '8d0e5e80-a569-4cbd-808e-220f4dd59953', 'type': 'tool_call'}] usage_metadata={'input_tokens': 389, 'output_tokens': 5, 'total_tokens': 394, 'input_token_details': {'cache_read': 0}}\n", - "\n", - "-------------------- Tool (Wikipedia) has been called --------------------\n", - "\n", - "The query is: Mercedes Sosa discography\n", - "\n", - "-------------------- Agent has been called -----------------------------------\n", - "\n", - "\n", - "The Prompt is: messages=[SystemMessage(content='# Task: Answering GAIA Benchmark Questions\\nYou are tasked with answering questions from the GAIA benchmark for AI agents.\\n\\nProvide ONLY the precise answer to the question. Do not include explanations, reasoning, or any additional text. Be direct, specific, and concise to meet the strict exact-matching requirements of the GAIA benchmark.\\n\\n# Output Format\\n- **Single-word or short-phrase answers:** If the question necessitates a brief answer, provide just that word or phrase.\\n- **Numerical values:** Provide only the number when applicable, with no additional formatting or units unless specifically requested.\\n- **Full sentences:** If the question expects a sentence, provide the exact sentence required with no extra characters, punctuation, or formatting.\\n\\n# Notes\\n- Be aware of strict exact-matching requirements; even minor deviations can result in an incorrect response.\\n- If any ambiguity exists in the phrasing of the input, respond with an answer that aligns with the GAIA benchmark\\'s intended interpretation.\"\"\"), (\"user\", question)])\\n', additional_kwargs={}, response_metadata={}), HumanMessage(content='How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia.', additional_kwargs={}, response_metadata={}, id='68e50b88-39ef-4456-a26d-736685236c92'), HumanMessage(content='Write a plan how to solve this qustion?', additional_kwargs={}, response_metadata={}, id='a851377d-2099-4c11-b2b9-35ce01592bdc'), AIMessage(content='1. Access the English Wikipedia (2022 version if possible).\\n2. Search for \"Mercedes Sosa discography\".\\n3. Identify the \"Studio albums\" section.\\n4. Filter the albums listed to include only those released between 2000 and 2009 (inclusive).\\n5. Count the number of albums that meet the criteria.\\n6. Provide the count as the answer.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-918a04ec-90ff-48b1-a056-be00c1fdb3c4-0', usage_metadata={'input_tokens': 259, 'output_tokens': 87, 'total_tokens': 346, 'input_token_details': {'cache_read': 0}}), HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={}, id='d8575e23-de1c-4c4a-907c-f8d383d61331'), AIMessage(content='', additional_kwargs={'function_call': {'name': 'retrieve', 'arguments': '{\"query\": \"Mercedes Sosa discography\"}'}}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-21ed6b3d-23db-4acc-88c4-4800f901a701-0', tool_calls=[{'name': 'retrieve', 'args': {'query': 'Mercedes Sosa discography'}, 'id': '8d0e5e80-a569-4cbd-808e-220f4dd59953', 'type': 'tool_call'}], usage_metadata={'input_tokens': 389, 'output_tokens': 5, 'total_tokens': 394, 'input_token_details': {'cache_read': 0}}), ToolMessage(content='\\nContent:\\nHaydée Mercedes \"La Negra\" Sosa (Latin American Spanish: [meɾˈseðes ˈsosa]; 9 July 1935 – 4 October 2009) was an Argentine singer who was popular throughout Latin America and many countries outside the region. With her roots in Argentine folk music, Sosa became one of the preeminent exponents of El nuevo cancionero. She gave voice to songs written by many Latin American songwriters. Her music made people hail her as the \"voice of the voiceless ones\". She was often called \"the conscience of Latin America\".\\nSosa performed in venues such as the Lincoln Center in New York City, the Théâtre Mogador in Paris, the Sistine Chapel in Vatican City, as well as sold-out shows in New York\\'s Carnegie Hall and the Roman Colosseum during her final decade of life. Her career spanned four decades and she was the recipient of six Latin Grammy awards (2000, 2003, 2004, 2006, 2009, 2011), including a Latin Grammy Lifetime Achievement Award in 2004 and two posthumous Latin Grammy Award for Best Folk Album in 2009 and 2011. She won the Premio Gardel in 2000, the main musical award in Argentina. She served as an ambassador for UNICEF.\\n\\n\\n== Life ==\\nSosa was born on 9 July 1935, in San Miguel de Tucumán, in the northwestern Argentine province of Tucumán, of mestizo ancestry. She was of French, Spanish and Diaguita descent. Her nickname \"la negra\", which is a common nickname in Argentina for people with darker complexion, is a reference to her indigenous heritage. Her parents, a day laborer and a washerwoman, were Peronists, although they never registered in the party, and she started her career as a singer for the Peronist Party in Tucuman under the name Gladys Osorio. In 1950, at age fifteen, she won a singing competition organized by a local radio station and was given a contract to perform for two months. She recorded her first album, La Voz de la Zafra, in 1959. A performance at the 1965 Cosquín National Folklore Festival—where she was introduced and brought to the stage while sitting in the audience by fellow folk singer Jorge Cafrune— brought her to the attention of the Argentine public. Sosa and her first husband, Manuel Oscar Matus, with whom she had one son, were key players in the mid-60s nueva canción movement (which was called nuevo cancionero in Argentina). Her second record was Canciones con Fundamento, a collection of Argentine folk songs.\\n\\nSosa \"spent the late 1960s building her audience in Europe and among the cosmopolitan middle class in Buenos Aires, becoming in the process a much bigger star\" than her contemporaries.In 1967, Sosa toured the United States and Europe with great success. In later years, she performed and recorded extensively, broadening her repertoire to include material from throughout Latin America.\\nIn the early 1970s, Sosa released two concept albums in collaboration with composer Ariel Ramírez and lyricist Félix Luna: Cantata Sudamericana and Mujeres Argentinas (Argentine Women). She also recorded a tribute to Chilean musician Violeta Parra in 1971, including what was to become one of Sosa\\'s signature songs, Gracias a la vida. She further popularized of songs written by Milton Nascimento of Brazil and Pablo Milanés and Silvio Rodríguez both from Cuba. Throughout the decade, she released albums such as Hasta la Victoria in 1972 and Traigo un Pueblo en mi Voz in 1973. They featured songs like \"Cuando tenga la tierra\", written by Ariel Petrocelli and Daniel Toro, which tackles political and social issues like wealth and land inequality. During the 1970s she was a part of two films by the director Leopoldo Torre Nilsson: El Santo de la Espada in 1970 and Güemes, la tierra en armas in 1971, in which she portrayed Juana Azurduy de Padilla, the guerrilla military leader who fought for Argentine independence.\\n\\nAfter the military junta of Jorge Videla came to power in 1976, the atmosphere in Argentina grew increasingly oppressive. Sosa faced death threats against both her and her family, but refused for many years to leave \\n\\n\\nContent:\\nThis is a discography for American folk singer and songwriter Joan Baez.\\n\\n\\n== Studio albums ==\\n\\n\\n=== 1959 ===\\n\"Folksingers \\'Round Harvard Square\" 1959 - with Bill Wood and Ted Alevizos\\n\\n\\n=== 1960s ===\\n\\n\\n=== 1970s ===\\n\\n\\n=== 1980–present ===\\n\\n\\n== Live albums ==\\n\\n\\n== Soundtrack albums ==\\nSacco & Vanzetti, RCA Victor (1971)\\nCarry It On, Vanguard (1971)\\nSilent Running, Decca (1972)\\nHow Sweet the Sound, Razor & Tie (2009)\\n\\n\\n== Compilations ==\\nFolksingers \\'Round Harvard Square (1959) / Re-Released as The Best of Joan Baez, Squire (1963)#45 POP\\nPortrait of Joan Baez (1967) (UK Only)\\nJoan Baez On Vanguard (1969) (UK Only) #15 UK\\nThe First 10 Years, Vanguard (November 1970) #73 US #41 UK #37 CAN\\nThe Joan Baez Ballad Book, Vanguard (1972) #188 US\\nHits: Greatest and Others, Vanguard (1973) #163 US, #63 Australia\\nThe Contemporary Ballad Book, Vanguard (1974)\\nThe Joan Baez Lovesong Album, Vanguard (1976) #205 US\\nBest of Joan C. Baez, A&M (1977) #121 US\\nThe Joan Baez Country Music Album (1979)\\nVery Early Joan, Vanguard (1982)\\nJoan Baez: Classics, A&M (1986)\\nBrothers in Arms, Gold Castle (1991)\\nNo Woman No Cry, Laserlight (February 1992)\\nRare, Live & Classic (box set), Vanguard (1993)\\nThe Best of Joan Baez, Vanguard (1995)\\nGreatest Hits, A&M (1996)\\nVanguard Sessions: Baez Sings Dylan, Vanguard (1998)\\nImagine, Universal 1998\\nBest of Joan Baez: The Millennium Collection, A&M/Universal (1999)\\nThe Complete A&M Recordings, Universal/A&M (2003)\\nVanguard Visionaries: Joan Baez, Vanguard (2007)\\nThe Complete Gold Castle Masters (box set), Razor & Tie (2017)\\n\\n\\n== Singles ==\\n\\n\\n== EPs ==\\nSilver Dagger & Other Songs, Fontana (1961) UK\\nWith God on Our Side, Fontana (1963) UK\\nDon\\'t Think Twice, It\\'s All Right, Fontana (1963) UK\\nLuv Is the Foundation w/ Rocker-T (2009) US\\n\\n\\n== Video albums ==\\nIn Concert, Pioneer (VHS, Laserdisc 1990)\\nLive at Sing Sing, NY 1972 (w/ B.B. King), (DVD 2004)\\nThree Voices: Live in Concert (1988 concert w/ Konstantin Wecker & Mercedes Sosa), (DVD 2004)\\nHow Sweet the Sound, American Masters/Razor & Tie (DVD 2009)\\nGolden Hits: Live Collection, Blueline (DVD 2013)\\nOh Freedom: Live in London, Hudson Street (DVD 2014)\\n75th Birthday Celebration, Razor & Tie (DVD 2016)\\n\\n\\n== Contributions ==\\nHard Rain by Bob Dylan (1976) - guitar, background vocals\\n4 Songs From Renaldo and Clara EP by Bob Dylan (1978) - vocals on \"Never Let Me Go\"\\nThe Butterfly Tree by Julia Butterfly Hill, Joan Baez, Joy Carlin, Berkeley Symphony Orchestra & Kent Nagano (2002) - vocals\\nThe Bootleg Series Vol. 5: Bob Dylan Live 1975, The Rolling Thunder Revue (2002) - vocals, acoustic guitar & percussion on 4 songs\\nThe Bootleg Series Vol. 6: Bob Dylan Live 1964, Concert at Philharmonic Hall (2004) - vocals on 4 songs\\nCorazón libre by Mercedes Sosa (2005) - cover art\\nBorn to the Breed: A Tribute to Judy Collins (2008) - \"Since You\\'ve Asked\"\\nJourney to the New World by Sharon Isbin, Joan Baez & Mark O\\'Connor (2009) - \"Joan Baez Suite Op. 144\" & \"Go \\'Way from My Window\"\\nTune In, Turn Up, Sing Out by San Francisco Gay Men\\'s Chorus (2009) - \"Swingin with the Saints\" & \"Imagine\"\\nBob Dylan – The Rolling Thunder Revue: The 1975 Live Recordings (2019) - vocals, acoustic guitar & percussion on 12 songs\\nAls teus ulls by Mario Muñoz feat. Lluís Llach, Gemma Humet & Joan Baez (2019) - single\\n\\n\\n== References ==\\n\\n\\n== External links ==\\nJoan Baez discography at Discogs\\n\\n\\nContent:\\nCantora, un Viaje Íntimo (English: Cantora, An Intimate Journey) is a double album by Argentine singer Mercedes Sosa, released on 2009 through Sony Music Argentina. The album features Cantora 1 and Cantora 2, the project is Sosa\\'s final album before her death on October 4, 2009.\\nAt the 10th Annual Latin Grammy Awards, Cantora 1 was nominated for Album of the Year and won Best Folk Album and Best Recording Package, the latter award went to Alejandro Ros, the art director of the album. Additionally, Sosa won two out of five nominations for the albums at the Gardel Awards 2010, the double album was nominated for Album of the Year and Production of the Year and won Best DVD while both Cantora 1 and Cantora 2 were nominated for Best Female Folk Album, with the former winning the category.\\nThe double album was a commercial success, being certified platinum by the CAPIF selling more than 200,000 copies in Argentina, Cantora 1 was also certified platinum selling 40,000 copies while Cantora 2 was certified gold selling 20,000 copies. The album also peaked at numbers 22 and 8 at the Top Latin Albums and Latin Pop Albums charts in United States, respectively, being Sosa\\'s only appearances on both charts.\\nAt documentary film titled Mercedes Sosa, Cantora un viaje íntimo was released on 2009, it was directed by Rodrigo Vila and features the recording process of the album as well as testimonies from the different guest artists that appeared on the project.\\n\\n\\n== Background ==\\nThe albums were produced by Popi Spatocco, frequent collaborator of Sosa, engineered by Jorge \"Portugués\" Da Silva and recorded from May 2008 to June 2009 at Estudios Panda and Estudios Ion, both in Buenos Aires, Argentina, the first session took place at Estudios Panda while the rest of the album was recorded at Estudios Ion, the first songs to be recorded were \"Agua, Fuego, Tierra y Viento\" with Argentine singer Soledad Pastorutti and \"Misionera\" with Brazilian accordionist Luiz Carlos Borges, the recording of the album was marked by interruptions due to the delicate health condition of Sosa, she would eventually die on October 16, 2009 at age 74, a couple of months following the release of the albums, about Cantora, Spatocco said that \"it was like receiving a diploma of honor, she was dedicated to whatever happened because she knew that I had her back\".\\n\\n\\n== Content ==\\nThe album contains a series of duet versions of songs alongside different artists from both Argentina, as well as from other countries such as Mexico, Uruguay, Brazil, Colombia, Spain and Venezuela. The variety of songs included range from songs performed with their original artist to songs performed with artists different than their original performer, many of the artists featured make reprises of their own songs for the album like Gustavo Cerati in the version of Soda Stereo\\'s \"Zonas de Promesas\", Charly García in the version of Serú Girán\\'s \"Desarma y Sangra\" and Luis Alberto Spinetta in the version of his song \"Barro Tal Vez\", while others appear in versions of songs not from their discography, like Shakira, who features in the track \"La Maza\", originally written and performed by Silvio Rodríguez, and Vicentico who appears the version of Ruben Blades\\'s \"Parao\". The albums end with a version of the Argentine National Anthem, being the only song in the albums to not feature a particular singer.\\n\\n\\n== Critical reception ==\\n\\nMariano Prunes from AllMusic gave both volumes of the album three and a half stars out of five. In his review for Cantora 1 he wrote that \"contrary to the quintessential Sosa recordings, Cantora is a fairly subdued affair, with most songs whispered against unobtrusive yet tasteful acoustic arrangements by Poppi Spatocco\", also commenting that the production \"certainly works very well, as it creates an encompassing sonic texture that helps to render the entire album less dissimilar than it may have been\". In the review for Cantora 2 he wrote that both albums as a whole are \"a touchi', name='retrieve', id='32c45159-7fc4-44f4-aed5-d39efbc68757', tool_call_id='8d0e5e80-a569-4cbd-808e-220f4dd59953'), HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={})] \n", - "\n", - "Agent has made a decision:\n", - " content='' additional_kwargs={'function_call': {'name': 'online_search', 'arguments': '{\"query\": \"Mercedes Sosa discography\"}'}} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-03cf1448-c06c-426e-b205-39491e210183-0' tool_calls=[{'name': 'online_search', 'args': {'query': 'Mercedes Sosa discography'}, 'id': 'd7b5be2b-5e4a-41ca-bdac-47a38e5c44d7', 'type': 'tool_call'}] usage_metadata={'input_tokens': 3407, 'output_tokens': 7, 'total_tokens': 3414, 'input_token_details': {'cache_read': 0}} [{'name': 'online_search', 'args': {'query': 'Mercedes Sosa discography'}, 'id': 'd7b5be2b-5e4a-41ca-bdac-47a38e5c44d7', 'type': 'tool_call'}]\n", - "Type von der Antwort: \n", - "\n", - "-------------------- Decision of forwarding has been made --------------------\n", - "\n", - "This is round: 3\n", - "The last message is: content='' additional_kwargs={'function_call': {'name': 'online_search', 'arguments': '{\"query\": \"Mercedes Sosa discography\"}'}} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-03cf1448-c06c-426e-b205-39491e210183-0' tool_calls=[{'name': 'online_search', 'args': {'query': 'Mercedes Sosa discography'}, 'id': 'd7b5be2b-5e4a-41ca-bdac-47a38e5c44d7', 'type': 'tool_call'}] usage_metadata={'input_tokens': 3407, 'output_tokens': 7, 'total_tokens': 3414, 'input_token_details': {'cache_read': 0}}\n", - "\n", - "-------------------- Tool (Tavily) has been called --------------------\n", - "\n", - "The query is: Mercedes Sosa discography\n", - "\n", - "-------------------- Agent has been called -----------------------------------\n", - "\n", - "\n", - "The Prompt is: messages=[SystemMessage(content='# Task: Answering GAIA Benchmark Questions\\nYou are tasked with answering questions from the GAIA benchmark for AI agents.\\n\\nProvide ONLY the precise answer to the question. Do not include explanations, reasoning, or any additional text. Be direct, specific, and concise to meet the strict exact-matching requirements of the GAIA benchmark.\\n\\n# Output Format\\n- **Single-word or short-phrase answers:** If the question necessitates a brief answer, provide just that word or phrase.\\n- **Numerical values:** Provide only the number when applicable, with no additional formatting or units unless specifically requested.\\n- **Full sentences:** If the question expects a sentence, provide the exact sentence required with no extra characters, punctuation, or formatting.\\n\\n# Notes\\n- Be aware of strict exact-matching requirements; even minor deviations can result in an incorrect response.\\n- If any ambiguity exists in the phrasing of the input, respond with an answer that aligns with the GAIA benchmark\\'s intended interpretation.\"\"\"), (\"user\", question)])\\n', additional_kwargs={}, response_metadata={}), HumanMessage(content='How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia.', additional_kwargs={}, response_metadata={}, id='68e50b88-39ef-4456-a26d-736685236c92'), HumanMessage(content='Write a plan how to solve this qustion?', additional_kwargs={}, response_metadata={}, id='a851377d-2099-4c11-b2b9-35ce01592bdc'), AIMessage(content='1. Access the English Wikipedia (2022 version if possible).\\n2. Search for \"Mercedes Sosa discography\".\\n3. Identify the \"Studio albums\" section.\\n4. Filter the albums listed to include only those released between 2000 and 2009 (inclusive).\\n5. Count the number of albums that meet the criteria.\\n6. Provide the count as the answer.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-918a04ec-90ff-48b1-a056-be00c1fdb3c4-0', usage_metadata={'input_tokens': 259, 'output_tokens': 87, 'total_tokens': 346, 'input_token_details': {'cache_read': 0}}), HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={}, id='d8575e23-de1c-4c4a-907c-f8d383d61331'), AIMessage(content='', additional_kwargs={'function_call': {'name': 'retrieve', 'arguments': '{\"query\": \"Mercedes Sosa discography\"}'}}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-21ed6b3d-23db-4acc-88c4-4800f901a701-0', tool_calls=[{'name': 'retrieve', 'args': {'query': 'Mercedes Sosa discography'}, 'id': '8d0e5e80-a569-4cbd-808e-220f4dd59953', 'type': 'tool_call'}], usage_metadata={'input_tokens': 389, 'output_tokens': 5, 'total_tokens': 394, 'input_token_details': {'cache_read': 0}}), ToolMessage(content='\\nContent:\\nHaydée Mercedes \"La Negra\" Sosa (Latin American Spanish: [meɾˈseðes ˈsosa]; 9 July 1935 – 4 October 2009) was an Argentine singer who was popular throughout Latin America and many countries outside the region. With her roots in Argentine folk music, Sosa became one of the preeminent exponents of El nuevo cancionero. She gave voice to songs written by many Latin American songwriters. Her music made people hail her as the \"voice of the voiceless ones\". She was often called \"the conscience of Latin America\".\\nSosa performed in venues such as the Lincoln Center in New York City, the Théâtre Mogador in Paris, the Sistine Chapel in Vatican City, as well as sold-out shows in New York\\'s Carnegie Hall and the Roman Colosseum during her final decade of life. Her career spanned four decades and she was the recipient of six Latin Grammy awards (2000, 2003, 2004, 2006, 2009, 2011), including a Latin Grammy Lifetime Achievement Award in 2004 and two posthumous Latin Grammy Award for Best Folk Album in 2009 and 2011. She won the Premio Gardel in 2000, the main musical award in Argentina. She served as an ambassador for UNICEF.\\n\\n\\n== Life ==\\nSosa was born on 9 July 1935, in San Miguel de Tucumán, in the northwestern Argentine province of Tucumán, of mestizo ancestry. She was of French, Spanish and Diaguita descent. Her nickname \"la negra\", which is a common nickname in Argentina for people with darker complexion, is a reference to her indigenous heritage. Her parents, a day laborer and a washerwoman, were Peronists, although they never registered in the party, and she started her career as a singer for the Peronist Party in Tucuman under the name Gladys Osorio. In 1950, at age fifteen, she won a singing competition organized by a local radio station and was given a contract to perform for two months. She recorded her first album, La Voz de la Zafra, in 1959. A performance at the 1965 Cosquín National Folklore Festival—where she was introduced and brought to the stage while sitting in the audience by fellow folk singer Jorge Cafrune— brought her to the attention of the Argentine public. Sosa and her first husband, Manuel Oscar Matus, with whom she had one son, were key players in the mid-60s nueva canción movement (which was called nuevo cancionero in Argentina). Her second record was Canciones con Fundamento, a collection of Argentine folk songs.\\n\\nSosa \"spent the late 1960s building her audience in Europe and among the cosmopolitan middle class in Buenos Aires, becoming in the process a much bigger star\" than her contemporaries.In 1967, Sosa toured the United States and Europe with great success. In later years, she performed and recorded extensively, broadening her repertoire to include material from throughout Latin America.\\nIn the early 1970s, Sosa released two concept albums in collaboration with composer Ariel Ramírez and lyricist Félix Luna: Cantata Sudamericana and Mujeres Argentinas (Argentine Women). She also recorded a tribute to Chilean musician Violeta Parra in 1971, including what was to become one of Sosa\\'s signature songs, Gracias a la vida. She further popularized of songs written by Milton Nascimento of Brazil and Pablo Milanés and Silvio Rodríguez both from Cuba. Throughout the decade, she released albums such as Hasta la Victoria in 1972 and Traigo un Pueblo en mi Voz in 1973. They featured songs like \"Cuando tenga la tierra\", written by Ariel Petrocelli and Daniel Toro, which tackles political and social issues like wealth and land inequality. During the 1970s she was a part of two films by the director Leopoldo Torre Nilsson: El Santo de la Espada in 1970 and Güemes, la tierra en armas in 1971, in which she portrayed Juana Azurduy de Padilla, the guerrilla military leader who fought for Argentine independence.\\n\\nAfter the military junta of Jorge Videla came to power in 1976, the atmosphere in Argentina grew increasingly oppressive. Sosa faced death threats against both her and her family, but refused for many years to leave \\n\\n\\nContent:\\nThis is a discography for American folk singer and songwriter Joan Baez.\\n\\n\\n== Studio albums ==\\n\\n\\n=== 1959 ===\\n\"Folksingers \\'Round Harvard Square\" 1959 - with Bill Wood and Ted Alevizos\\n\\n\\n=== 1960s ===\\n\\n\\n=== 1970s ===\\n\\n\\n=== 1980–present ===\\n\\n\\n== Live albums ==\\n\\n\\n== Soundtrack albums ==\\nSacco & Vanzetti, RCA Victor (1971)\\nCarry It On, Vanguard (1971)\\nSilent Running, Decca (1972)\\nHow Sweet the Sound, Razor & Tie (2009)\\n\\n\\n== Compilations ==\\nFolksingers \\'Round Harvard Square (1959) / Re-Released as The Best of Joan Baez, Squire (1963)#45 POP\\nPortrait of Joan Baez (1967) (UK Only)\\nJoan Baez On Vanguard (1969) (UK Only) #15 UK\\nThe First 10 Years, Vanguard (November 1970) #73 US #41 UK #37 CAN\\nThe Joan Baez Ballad Book, Vanguard (1972) #188 US\\nHits: Greatest and Others, Vanguard (1973) #163 US, #63 Australia\\nThe Contemporary Ballad Book, Vanguard (1974)\\nThe Joan Baez Lovesong Album, Vanguard (1976) #205 US\\nBest of Joan C. Baez, A&M (1977) #121 US\\nThe Joan Baez Country Music Album (1979)\\nVery Early Joan, Vanguard (1982)\\nJoan Baez: Classics, A&M (1986)\\nBrothers in Arms, Gold Castle (1991)\\nNo Woman No Cry, Laserlight (February 1992)\\nRare, Live & Classic (box set), Vanguard (1993)\\nThe Best of Joan Baez, Vanguard (1995)\\nGreatest Hits, A&M (1996)\\nVanguard Sessions: Baez Sings Dylan, Vanguard (1998)\\nImagine, Universal 1998\\nBest of Joan Baez: The Millennium Collection, A&M/Universal (1999)\\nThe Complete A&M Recordings, Universal/A&M (2003)\\nVanguard Visionaries: Joan Baez, Vanguard (2007)\\nThe Complete Gold Castle Masters (box set), Razor & Tie (2017)\\n\\n\\n== Singles ==\\n\\n\\n== EPs ==\\nSilver Dagger & Other Songs, Fontana (1961) UK\\nWith God on Our Side, Fontana (1963) UK\\nDon\\'t Think Twice, It\\'s All Right, Fontana (1963) UK\\nLuv Is the Foundation w/ Rocker-T (2009) US\\n\\n\\n== Video albums ==\\nIn Concert, Pioneer (VHS, Laserdisc 1990)\\nLive at Sing Sing, NY 1972 (w/ B.B. King), (DVD 2004)\\nThree Voices: Live in Concert (1988 concert w/ Konstantin Wecker & Mercedes Sosa), (DVD 2004)\\nHow Sweet the Sound, American Masters/Razor & Tie (DVD 2009)\\nGolden Hits: Live Collection, Blueline (DVD 2013)\\nOh Freedom: Live in London, Hudson Street (DVD 2014)\\n75th Birthday Celebration, Razor & Tie (DVD 2016)\\n\\n\\n== Contributions ==\\nHard Rain by Bob Dylan (1976) - guitar, background vocals\\n4 Songs From Renaldo and Clara EP by Bob Dylan (1978) - vocals on \"Never Let Me Go\"\\nThe Butterfly Tree by Julia Butterfly Hill, Joan Baez, Joy Carlin, Berkeley Symphony Orchestra & Kent Nagano (2002) - vocals\\nThe Bootleg Series Vol. 5: Bob Dylan Live 1975, The Rolling Thunder Revue (2002) - vocals, acoustic guitar & percussion on 4 songs\\nThe Bootleg Series Vol. 6: Bob Dylan Live 1964, Concert at Philharmonic Hall (2004) - vocals on 4 songs\\nCorazón libre by Mercedes Sosa (2005) - cover art\\nBorn to the Breed: A Tribute to Judy Collins (2008) - \"Since You\\'ve Asked\"\\nJourney to the New World by Sharon Isbin, Joan Baez & Mark O\\'Connor (2009) - \"Joan Baez Suite Op. 144\" & \"Go \\'Way from My Window\"\\nTune In, Turn Up, Sing Out by San Francisco Gay Men\\'s Chorus (2009) - \"Swingin with the Saints\" & \"Imagine\"\\nBob Dylan – The Rolling Thunder Revue: The 1975 Live Recordings (2019) - vocals, acoustic guitar & percussion on 12 songs\\nAls teus ulls by Mario Muñoz feat. Lluís Llach, Gemma Humet & Joan Baez (2019) - single\\n\\n\\n== References ==\\n\\n\\n== External links ==\\nJoan Baez discography at Discogs\\n\\n\\nContent:\\nCantora, un Viaje Íntimo (English: Cantora, An Intimate Journey) is a double album by Argentine singer Mercedes Sosa, released on 2009 through Sony Music Argentina. The album features Cantora 1 and Cantora 2, the project is Sosa\\'s final album before her death on October 4, 2009.\\nAt the 10th Annual Latin Grammy Awards, Cantora 1 was nominated for Album of the Year and won Best Folk Album and Best Recording Package, the latter award went to Alejandro Ros, the art director of the album. Additionally, Sosa won two out of five nominations for the albums at the Gardel Awards 2010, the double album was nominated for Album of the Year and Production of the Year and won Best DVD while both Cantora 1 and Cantora 2 were nominated for Best Female Folk Album, with the former winning the category.\\nThe double album was a commercial success, being certified platinum by the CAPIF selling more than 200,000 copies in Argentina, Cantora 1 was also certified platinum selling 40,000 copies while Cantora 2 was certified gold selling 20,000 copies. The album also peaked at numbers 22 and 8 at the Top Latin Albums and Latin Pop Albums charts in United States, respectively, being Sosa\\'s only appearances on both charts.\\nAt documentary film titled Mercedes Sosa, Cantora un viaje íntimo was released on 2009, it was directed by Rodrigo Vila and features the recording process of the album as well as testimonies from the different guest artists that appeared on the project.\\n\\n\\n== Background ==\\nThe albums were produced by Popi Spatocco, frequent collaborator of Sosa, engineered by Jorge \"Portugués\" Da Silva and recorded from May 2008 to June 2009 at Estudios Panda and Estudios Ion, both in Buenos Aires, Argentina, the first session took place at Estudios Panda while the rest of the album was recorded at Estudios Ion, the first songs to be recorded were \"Agua, Fuego, Tierra y Viento\" with Argentine singer Soledad Pastorutti and \"Misionera\" with Brazilian accordionist Luiz Carlos Borges, the recording of the album was marked by interruptions due to the delicate health condition of Sosa, she would eventually die on October 16, 2009 at age 74, a couple of months following the release of the albums, about Cantora, Spatocco said that \"it was like receiving a diploma of honor, she was dedicated to whatever happened because she knew that I had her back\".\\n\\n\\n== Content ==\\nThe album contains a series of duet versions of songs alongside different artists from both Argentina, as well as from other countries such as Mexico, Uruguay, Brazil, Colombia, Spain and Venezuela. The variety of songs included range from songs performed with their original artist to songs performed with artists different than their original performer, many of the artists featured make reprises of their own songs for the album like Gustavo Cerati in the version of Soda Stereo\\'s \"Zonas de Promesas\", Charly García in the version of Serú Girán\\'s \"Desarma y Sangra\" and Luis Alberto Spinetta in the version of his song \"Barro Tal Vez\", while others appear in versions of songs not from their discography, like Shakira, who features in the track \"La Maza\", originally written and performed by Silvio Rodríguez, and Vicentico who appears the version of Ruben Blades\\'s \"Parao\". The albums end with a version of the Argentine National Anthem, being the only song in the albums to not feature a particular singer.\\n\\n\\n== Critical reception ==\\n\\nMariano Prunes from AllMusic gave both volumes of the album three and a half stars out of five. In his review for Cantora 1 he wrote that \"contrary to the quintessential Sosa recordings, Cantora is a fairly subdued affair, with most songs whispered against unobtrusive yet tasteful acoustic arrangements by Poppi Spatocco\", also commenting that the production \"certainly works very well, as it creates an encompassing sonic texture that helps to render the entire album less dissimilar than it may have been\". In the review for Cantora 2 he wrote that both albums as a whole are \"a touchi', name='retrieve', id='32c45159-7fc4-44f4-aed5-d39efbc68757', tool_call_id='8d0e5e80-a569-4cbd-808e-220f4dd59953'), HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={}, id='4aecb0ce-8620-4333-86ba-83c9f059a635'), AIMessage(content='', additional_kwargs={'function_call': {'name': 'online_search', 'arguments': '{\"query\": \"Mercedes Sosa discography\"}'}}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-03cf1448-c06c-426e-b205-39491e210183-0', tool_calls=[{'name': 'online_search', 'args': {'query': 'Mercedes Sosa discography'}, 'id': 'd7b5be2b-5e4a-41ca-bdac-47a38e5c44d7', 'type': 'tool_call'}], usage_metadata={'input_tokens': 3407, 'output_tokens': 7, 'total_tokens': 3414, 'input_token_details': {'cache_read': 0}}), ToolMessage(content=\"Error: ImportError('Tavily python package not found. Please install it with `pip install tavily-python`.')\\n Please fix your mistakes.\", name='online_search', id='1aeacb93-b415-4a7a-a790-4e59eda45dda', tool_call_id='d7b5be2b-5e4a-41ca-bdac-47a38e5c44d7', status='error'), HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={})] \n", - "\n", - "Agent has made a decision:\n", - " content='Based on the Wikipedia search, Mercedes Sosa released the following studio albums between 2000 and 2009 (inclusive):\\n\\n* **2000**: *Misa Criolla*\\n* **2003**: *Argentina Quiero Verte Alegre*\\n* **2005**: *Corazón Libre*\\n* **2009**: *Cantora, un Viaje Íntimo*\\n\\nTherefore, the answer is 4.' additional_kwargs={} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-8a9922fa-3d4f-442a-a220-05c7f00d48c5-0' usage_metadata={'input_tokens': 3459, 'output_tokens': 101, 'total_tokens': 3560, 'input_token_details': {'cache_read': 0}} Based on the Wikipedia search, Mercedes Sosa released the following studio albums between 2000 and 2009 (inclusive):\n", - "\n", - "* **2000**: *Misa Criolla*\n", - "* **2003**: *Argentina Quiero Verte Alegre*\n", - "* **2005**: *Corazón Libre*\n", - "* **2009**: *Cantora, un Viaje Íntimo*\n", - "\n", - "Therefore, the answer is 4. []\n", - "Type von der Antwort: \n", - "\n", - "-------------------- Decision of forwarding has been made --------------------\n", - "\n", - "This is round: 4\n", - "The last message is: content='Based on the Wikipedia search, Mercedes Sosa released the following studio albums between 2000 and 2009 (inclusive):\\n\\n* **2000**: *Misa Criolla*\\n* **2003**: *Argentina Quiero Verte Alegre*\\n* **2005**: *Corazón Libre*\\n* **2009**: *Cantora, un Viaje Íntimo*\\n\\nTherefore, the answer is 4.' additional_kwargs={} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-8a9922fa-3d4f-442a-a220-05c7f00d48c5-0' usage_metadata={'input_tokens': 3459, 'output_tokens': 101, 'total_tokens': 3560, 'input_token_details': {'cache_read': 0}}\n" - ] - } - ], - "execution_count": 3 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T20:03:34.679809Z", - "start_time": "2025-04-27T20:03:34.674210Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "res[\"messages\"][-1].content", "id": "66f2dcaeb343c836", - "outputs": [ - { - "data": { - "text/plain": [ - "'4'" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 4 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T21:10:45.656951Z", - "start_time": "2025-04-27T21:10:45.649588Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "from langchain_community.retrievers import WikipediaRetriever\n", @@ -182,207 +63,40 @@ ], "id": "8d3a94be44f4859a", "outputs": [], - "execution_count": 3 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T17:12:14.733545300Z", - "start_time": "2025-04-27T17:05:15.822287Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "docs = retriever.invoke(query)\n", "id": "3bf392ddf3ce5c96", "outputs": [], - "execution_count": 25 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T17:12:14.733545300Z", - "start_time": "2025-04-27T16:59:49.891769Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "\n", "print(docs[0].page_content)" ], "id": "f8175b6bfcdac968", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Haydée Mercedes \"La Negra\" Sosa (Latin American Spanish: [meɾˈseðes ˈsosa]; 9 July 1935 – 4 October 2009) was an Argentine singer who was popular throughout Latin America and many countries outside the region. With her roots in Argentine folk music, Sosa became one of the preeminent exponents of El nuevo cancionero. She gave voice to songs written by many Latin American songwriters. Her music made people hail her as the \"voice of the voiceless ones\". She was often called \"the conscience of Latin America\".\n", - "Sosa performed in venues such as the Lincoln Center in New York City, the Théâtre Mogador in Paris, the Sistine Chapel in Vatican City, as well as sold-out shows in New York's Carnegie Hall and the Roman Colosseum during her final decade of life. Her career spanned four decades and she was the recipient of six Latin Grammy awards (2000, 2003, 2004, 2006, 2009, 2011), including a Latin Grammy Lifetime Achievement Award in 2004 and two posthumous Latin Grammy Award for Best Folk Album in 2009 and 2011. She won the Premio Gardel in 2000, the main musical award in Argentina. She served as an ambassador for UNICEF.\n", - "\n", - "\n", - "== Life ==\n", - "Sosa was born on 9 July 1935, in San Miguel de Tucumán, in the northwestern Argentine province of Tucumán, of mestizo ancestry. She was of French, Spanish and Diaguita descent. Her nickname \"la negra\", which is a common nickname in Argentina for people with darker complexion, is a reference to her indigenous heritage. Her parents, a day laborer and a washerwoman, were Peronists, although they never registered in the party, and she started her career as a singer for the Peronist Party in Tucuman under the name Gladys Osorio. In 1950, at age fifteen, she won a singing competition organized by a local radio station and was given a contract to perform for two months. She recorded her first album, La Voz de la Zafra, in 1959. A performance at the 1965 Cosquín National Folklore Festival—where she was introduced and brought to the stage while sitting in the audience by fellow folk singer Jorge Cafrune— brought her to the attention of the Argentine public. Sosa and her first husband, Manuel Oscar Matus, with whom she had one son, were key players in the mid-60s nueva canción movement (which was called nuevo cancionero in Argentina). Her second record was Canciones con Fundamento, a collection of Argentine folk songs.\n", - "\n", - "Sosa \"spent the late 1960s building her audience in Europe and among the cosmopolitan middle class in Buenos Aires, becoming in the process a much bigger star\" than her contemporaries.In 1967, Sosa toured the United States and Europe with great success. In later years, she performed and recorded extensively, broadening her repertoire to include material from throughout Latin America.\n", - "In the early 1970s, Sosa released two concept albums in collaboration with composer Ariel Ramírez and lyricist Félix Luna: Cantata Sudamericana and Mujeres Argentinas (Argentine Women). She also recorded a tribute to Chilean musician Violeta Parra in 1971, including what was to become one of Sosa's signature songs, Gracias a la vida. She further popularized of songs written by Milton Nascimento of Brazil and Pablo Milanés and Silvio Rodríguez both from Cuba. Throughout the decade, she released albums such as Hasta la Victoria in 1972 and Traigo un Pueblo en mi Voz in 1973. They featured songs like \"Cuando tenga la tierra\", written by Ariel Petrocelli and Daniel Toro, which tackles political and social issues like wealth and land inequality. During the 1970s she was a part of two films by the director Leopoldo Torre Nilsson: El Santo de la Espada in 1970 and Güemes, la tierra en armas in 1971, in which she portrayed Juana Azurduy de Padilla, the guerrilla military leader who fought for Argentine independence.\n", - "\n", - "After the military junta of Jorge Videla came to power in 1976, the atmosphere in Argentina grew increasingly oppressive. Sosa faced death threats against both her and her family, but refused for many years to leave \n" - ] - } - ], - "execution_count": 17 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T17:12:14.742545100Z", - "start_time": "2025-04-27T17:05:20.536807Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "for doc in docs:\n", " print(doc.page_content)\n" ], "id": "43fc5252d21e3f51", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Haydée Mercedes \"La Negra\" Sosa (Latin American Spanish: [meɾˈseðes ˈsosa]; 9 July 1935 – 4 October 2009) was an Argentine singer who was popular throughout Latin America and many countries outside the region. With her roots in Argentine folk music, Sosa became one of the preeminent exponents of El nuevo cancionero. She gave voice to songs written by many Latin American songwriters. Her music made people hail her as the \"voice of the voiceless ones\". She was often called \"the conscience of Latin America\".\n", - "Sosa performed in venues such as the Lincoln Center in New York City, the Théâtre Mogador in Paris, the Sistine Chapel in Vatican City, as well as sold-out shows in New York's Carnegie Hall and the Roman Colosseum during her final decade of life. Her career spanned four decades and she was the recipient of six Latin Grammy awards (2000, 2003, 2004, 2006, 2009, 2011), including a Latin Grammy Lifetime Achievement Award in 2004 and two posthumous Latin Grammy Award for Best Folk Album in 2009 and 2011. She won the Premio Gardel in 2000, the main musical award in Argentina. She served as an ambassador for UNICEF.\n", - "\n", - "\n", - "== Life ==\n", - "Sosa was born on 9 July 1935, in San Miguel de Tucumán, in the northwestern Argentine province of Tucumán, of mestizo ancestry. She was of French, Spanish and Diaguita descent. Her nickname \"la negra\", which is a common nickname in Argentina for people with darker complexion, is a reference to her indigenous heritage. Her parents, a day laborer and a washerwoman, were Peronists, although they never registered in the party, and she started her career as a singer for the Peronist Party in Tucuman under the name Gladys Osorio. In 1950, at age fifteen, she won a singing competition organized by a local radio station and was given a contract to perform for two months. She recorded her first album, La Voz de la Zafra, in 1959. A performance at the 1965 Cosquín National Folklore Festival—where she was introduced and brought to the stage while sitting in the audience by fellow folk singer Jorge Cafrune— brought her to the attention of the Argentine public. Sosa and her first husband, Manuel Oscar Matus, with whom she had one son, were key players in the mid-60s nueva canción movement (which was called nuevo cancionero in Argentina). Her second record was Canciones con Fundamento, a collection of Argentine folk songs.\n", - "\n", - "Sosa \"spent the late 1960s building her audience in Europe and among the cosmopolitan middle class in Buenos Aires, becoming in the process a much bigger star\" than her contemporaries.In 1967, Sosa toured the United States and Europe with great success. In later years, she performed and recorded extensively, broadening her repertoire to include material from throughout Latin America.\n", - "In the early 1970s, Sosa released two concept albums in collaboration with composer Ariel Ramírez and lyricist Félix Luna: Cantata Sudamericana and Mujeres Argentinas (Argentine Women). She also recorded a tribute to Chilean musician Violeta Parra in 1971, including what was to become one of Sosa's signature songs, Gracias a la vida. She further popularized of songs written by Milton Nascimento of Brazil and Pablo Milanés and Silvio Rodríguez both from Cuba. Throughout the decade, she released albums such as Hasta la Victoria in 1972 and Traigo un Pueblo en mi Voz in 1973. They featured songs like \"Cuando tenga la tierra\", written by Ariel Petrocelli and Daniel Toro, which tackles political and social issues like wealth and land inequality. During the 1970s she was a part of two films by the director Leopoldo Torre Nilsson: El Santo de la Espada in 1970 and Güemes, la tierra en armas in 1971, in which she portrayed Juana Azurduy de Padilla, the guerrilla military leader who fought for Argentine independence.\n", - "\n", - "After the military junta of Jorge Videla came to power in 1976, the atmosphere in Argentina grew increasingly oppressive. Sosa faced death threats against both her and her family, but refused for many years to leave \n", - "This is a discography for American folk singer and songwriter Joan Baez.\n", - "\n", - "\n", - "== Studio albums ==\n", - "\n", - "\n", - "=== 1959 ===\n", - "\"Folksingers 'Round Harvard Square\" 1959 - with Bill Wood and Ted Alevizos\n", - "\n", - "\n", - "=== 1960s ===\n", - "\n", - "\n", - "=== 1970s ===\n", - "\n", - "\n", - "=== 1980–present ===\n", - "\n", - "\n", - "== Live albums ==\n", - "\n", - "\n", - "== Soundtrack albums ==\n", - "Sacco & Vanzetti, RCA Victor (1971)\n", - "Carry It On, Vanguard (1971)\n", - "Silent Running, Decca (1972)\n", - "How Sweet the Sound, Razor & Tie (2009)\n", - "\n", - "\n", - "== Compilations ==\n", - "Folksingers 'Round Harvard Square (1959) / Re-Released as The Best of Joan Baez, Squire (1963)#45 POP\n", - "Portrait of Joan Baez (1967) (UK Only)\n", - "Joan Baez On Vanguard (1969) (UK Only) #15 UK\n", - "The First 10 Years, Vanguard (November 1970) #73 US #41 UK #37 CAN\n", - "The Joan Baez Ballad Book, Vanguard (1972) #188 US\n", - "Hits: Greatest and Others, Vanguard (1973) #163 US, #63 Australia\n", - "The Contemporary Ballad Book, Vanguard (1974)\n", - "The Joan Baez Lovesong Album, Vanguard (1976) #205 US\n", - "Best of Joan C. Baez, A&M (1977) #121 US\n", - "The Joan Baez Country Music Album (1979)\n", - "Very Early Joan, Vanguard (1982)\n", - "Joan Baez: Classics, A&M (1986)\n", - "Brothers in Arms, Gold Castle (1991)\n", - "No Woman No Cry, Laserlight (February 1992)\n", - "Rare, Live & Classic (box set), Vanguard (1993)\n", - "The Best of Joan Baez, Vanguard (1995)\n", - "Greatest Hits, A&M (1996)\n", - "Vanguard Sessions: Baez Sings Dylan, Vanguard (1998)\n", - "Imagine, Universal 1998\n", - "Best of Joan Baez: The Millennium Collection, A&M/Universal (1999)\n", - "The Complete A&M Recordings, Universal/A&M (2003)\n", - "Vanguard Visionaries: Joan Baez, Vanguard (2007)\n", - "The Complete Gold Castle Masters (box set), Razor & Tie (2017)\n", - "\n", - "\n", - "== Singles ==\n", - "\n", - "\n", - "== EPs ==\n", - "Silver Dagger & Other Songs, Fontana (1961) UK\n", - "With God on Our Side, Fontana (1963) UK\n", - "Don't Think Twice, It's All Right, Fontana (1963) UK\n", - "Luv Is the Foundation w/ Rocker-T (2009) US\n", - "\n", - "\n", - "== Video albums ==\n", - "In Concert, Pioneer (VHS, Laserdisc 1990)\n", - "Live at Sing Sing, NY 1972 (w/ B.B. King), (DVD 2004)\n", - "Three Voices: Live in Concert (1988 concert w/ Konstantin Wecker & Mercedes Sosa), (DVD 2004)\n", - "How Sweet the Sound, American Masters/Razor & Tie (DVD 2009)\n", - "Golden Hits: Live Collection, Blueline (DVD 2013)\n", - "Oh Freedom: Live in London, Hudson Street (DVD 2014)\n", - "75th Birthday Celebration, Razor & Tie (DVD 2016)\n", - "\n", - "\n", - "== Contributions ==\n", - "Hard Rain by Bob Dylan (1976) - guitar, background vocals\n", - "4 Songs From Renaldo and Clara EP by Bob Dylan (1978) - vocals on \"Never Let Me Go\"\n", - "The Butterfly Tree by Julia Butterfly Hill, Joan Baez, Joy Carlin, Berkeley Symphony Orchestra & Kent Nagano (2002) - vocals\n", - "The Bootleg Series Vol. 5: Bob Dylan Live 1975, The Rolling Thunder Revue (2002) - vocals, acoustic guitar & percussion on 4 songs\n", - "The Bootleg Series Vol. 6: Bob Dylan Live 1964, Concert at Philharmonic Hall (2004) - vocals on 4 songs\n", - "Corazón libre by Mercedes Sosa (2005) - cover art\n", - "Born to the Breed: A Tribute to Judy Collins (2008) - \"Since You've Asked\"\n", - "Journey to the New World by Sharon Isbin, Joan Baez & Mark O'Connor (2009) - \"Joan Baez Suite Op. 144\" & \"Go 'Way from My Window\"\n", - "Tune In, Turn Up, Sing Out by San Francisco Gay Men's Chorus (2009) - \"Swingin with the Saints\" & \"Imagine\"\n", - "Bob Dylan – The Rolling Thunder Revue: The 1975 Live Recordings (2019) - vocals, acoustic guitar & percussion on 12 songs\n", - "Als teus ulls by Mario Muñoz feat. Lluís Llach, Gemma Humet & Joan Baez (2019) - single\n", - "\n", - "\n", - "== References ==\n", - "\n", - "\n", - "== External links ==\n", - "Joan Baez discography at Discogs\n", - "Cantora, un Viaje Íntimo (English: Cantora, An Intimate Journey) is a double album by Argentine singer Mercedes Sosa, released on 2009 through Sony Music Argentina. The album features Cantora 1 and Cantora 2, the project is Sosa's final album before her death on October 4, 2009.\n", - "At the 10th Annual Latin Grammy Awards, Cantora 1 was nominated for Album of the Year and won Best Folk Album and Best Recording Package, the latter award went to Alejandro Ros, the art director of the album. Additionally, Sosa won two out of five nominations for the albums at the Gardel Awards 2010, the double album was nominated for Album of the Year and Production of the Year and won Best DVD while both Cantora 1 and Cantora 2 were nominated for Best Female Folk Album, with the former winning the category.\n", - "The double album was a commercial success, being certified platinum by the CAPIF selling more than 200,000 copies in Argentina, Cantora 1 was also certified platinum selling 40,000 copies while Cantora 2 was certified gold selling 20,000 copies. The album also peaked at numbers 22 and 8 at the Top Latin Albums and Latin Pop Albums charts in United States, respectively, being Sosa's only appearances on both charts.\n", - "At documentary film titled Mercedes Sosa, Cantora un viaje íntimo was released on 2009, it was directed by Rodrigo Vila and features the recording process of the album as well as testimonies from the different guest artists that appeared on the project.\n", - "\n", - "\n", - "== Background ==\n", - "The albums were produced by Popi Spatocco, frequent collaborator of Sosa, engineered by Jorge \"Portugués\" Da Silva and recorded from May 2008 to June 2009 at Estudios Panda and Estudios Ion, both in Buenos Aires, Argentina, the first session took place at Estudios Panda while the rest of the album was recorded at Estudios Ion, the first songs to be recorded were \"Agua, Fuego, Tierra y Viento\" with Argentine singer Soledad Pastorutti and \"Misionera\" with Brazilian accordionist Luiz Carlos Borges, the recording of the album was marked by interruptions due to the delicate health condition of Sosa, she would eventually die on October 16, 2009 at age 74, a couple of months following the release of the albums, about Cantora, Spatocco said that \"it was like receiving a diploma of honor, she was dedicated to whatever happened because she knew that I had her back\".\n", - "\n", - "\n", - "== Content ==\n", - "The album contains a series of duet versions of songs alongside different artists from both Argentina, as well as from other countries such as Mexico, Uruguay, Brazil, Colombia, Spain and Venezuela. The variety of songs included range from songs performed with their original artist to songs performed with artists different than their original performer, many of the artists featured make reprises of their own songs for the album like Gustavo Cerati in the version of Soda Stereo's \"Zonas de Promesas\", Charly García in the version of Serú Girán's \"Desarma y Sangra\" and Luis Alberto Spinetta in the version of his song \"Barro Tal Vez\", while others appear in versions of songs not from their discography, like Shakira, who features in the track \"La Maza\", originally written and performed by Silvio Rodríguez, and Vicentico who appears the version of Ruben Blades's \"Parao\". The albums end with a version of the Argentine National Anthem, being the only song in the albums to not feature a particular singer.\n", - "\n", - "\n", - "== Critical reception ==\n", - "\n", - "Mariano Prunes from AllMusic gave both volumes of the album three and a half stars out of five. In his review for Cantora 1 he wrote that \"contrary to the quintessential Sosa recordings, Cantora is a fairly subdued affair, with most songs whispered against unobtrusive yet tasteful acoustic arrangements by Poppi Spatocco\", also commenting that the production \"certainly works very well, as it creates an encompassing sonic texture that helps to render the entire album less dissimilar than it may have been\". In the review for Cantora 2 he wrote that both albums as a whole are \"a touchi\n" - ] - } - ], - "execution_count": 26 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T21:10:48.436586Z", - "start_time": "2025-04-27T21:10:48.432601Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "from langchain_community.retrievers import TavilySearchAPIRetriever\n", @@ -391,36 +105,26 @@ ], "id": "e7437de8b64432f3", "outputs": [], - "execution_count": 4 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T21:11:28.132221Z", - "start_time": "2025-04-27T21:11:26.234842Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "docs = retriever.invoke(query)", "id": "f7b6c17ac86da2d5", "outputs": [], - "execution_count": 6 + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "5456b2d077ac90f9" + "id": "5456b2d077ac90f9", + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T21:11:30.551965Z", - "start_time": "2025-04-27T21:11:30.547552Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "serialized = \"\\n\\n\".join(\n", @@ -430,39 +134,18 @@ ], "id": "e9027ea921f537e4", "outputs": [], - "execution_count": 7 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-27T21:11:34.971188Z", - "start_time": "2025-04-27T21:11:34.965978Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "serialized", "id": "271efb15048278d8", - "outputs": [ - { - "data": { - "text/plain": [ - "'\\nContent:\\nMercedes Sosa Discography Aufnahmen vor dem Exil Cancíones con fundamento (1959) La voz de la zafra (1961) Hermano (1966) Yo no canto por cantar (1966) Para cantarle a mi gente (1967) Con sabor a Mercedes Sosa (1968) Mujeres Argentinas (1969) El grito de la tierra (1970) Navidad con Mercedes Sosa (1970) Guemes el guerrillero del norte (1971) Homenaje a Violeta Parra (1971) Cantata Sudamericana (1972) Hasta la victoria (1972) Mercedes Sosa y Horacio Guarany (single 1973) Traigo un pueblo en mi voz (1973) Mercedes Sosa y Horacio Guarny (single 1974) A que florezca mi pueblo (1975) Niño de mañana (1975) En dirección del viento (1976) Mercedes Sosa (1976) Mercedes Sosa interpreta a Atahualpa Yupanqui (1977) O cio da terra (1977) (1977) Aufnahmen nach dem Exil Serenata para la tierra de uno (1979) Gravado ao vivo no Brasil (1980) A quién doy (1981) Mercedes Sosa en Argentina (1982) Como un pájaro libre (1983) Mercedes Sosa (1983) Recital (1983) ¿Será posible el sur? (1984) Corazón Americano (1985) (con Milton Nascimento y León Gieco) Vengo a ofrecer mi corazón (1985) Mercedes Sosa \\'86 (1986) Mercedes Sosa \\'87 (1987) Gracias a la vida (1987) Amigos míos (1988) Live in Europa (1990) De mí (1991) 30 años (1993) Sino (1993) Gestos de amor (1994) Oro (1995) Escondido en mi país (1996) Alta fidelidad (1997) (con Charly García) Al despertar (1998) Misa Criolla (2000) Acústico (2002) Argentina quiere cantar (2003) (con Víctor Heredia & León Gieco) Corazón libre (2005) Cantora (2009) Posthum veröffentliche Aufnahmen: Deja la Vidavolar (2010) Censurada (2011) Siempre en Ti (2013) Selva Sola (2013) Angel (2014) Lucerito (2015) thhhext.\\n\\n\\nContent:\\nMercedes Sosa | Discogs EverythingReleasesArtistsLabels View all results Explore Discover Explore All Trending Releases List Explorer Advanced Search Contribute Submission Guidelines Submit a Release How to Make a List Monthly Leaderboard Help Translate Discogs Genres Rock Electronic Hip Hop Folk, World, & Country Jazz Styles House Punk Soul Experimental Prog Rock Marketplace Format Vinyl CD Cassette DVD Box Set Genre Rock Electronic Pop Funk / Soul Jazz Styles Pop Rock House Disco Synth-Pop Soul Buy Music All Items Items I Want Purchases Cart Record Stores Sell Music Start Selling List Item For Sale Orders Inventory Billing Community Discogs Digs Groups Forum Friends Community Guidelines Database Guidelines Explore Discover Explore All Trending Releases List Explorer Advanced Search Contribute Submission Guidelines Submit a Release How to Make a List Monthly Leaderboard Help Translate Discogs Genres Rock Electronic Hip Hop Folk, World, & Country Jazz Styles House Punk Soul Experimental Prog Rock Marketplace Format Vinyl CD Cassette DVD Box Set Genre Rock Electronic Pop Funk / Soul Jazz Styles Pop Rock House Disco Synth-Pop Soul Buy Music All Items Items I Want Purchases Cart Record Stores Sell Music Start Selling List Item For Sale Orders Inventory Billing Community Discogs Digs Groups Forum Friends Community Guidelines Database Guidelines Log InRegister Ad Mercedes Sosa More images .css-1kybk0l{margin:0;font-size:0.875rem;font-weight:400;letter-spacing:0.01em;line-height:1.2;}Profile:Mercedes Sosa, known as La Negra, (born July 9, 1935 in San Miguel de Tucuman, Argentina – Death October 4, 2009 in Buenos Aires) was an Argentine singer who was and remains immensely popular throughout Latin America and internationally. With her roots in Argentine folk music, in 1950, at age fifteen, she won a singing competition organized by a local radio station, and in the 1960s Sosa became one of the preeminent exponents of \\'nueva canción\\' and started touring internationally. She also gave voice to many songs written by Brazilians and Cubans. She was best known as the \\'voice of the voiceless ones\\'. Banned in her own country, she moved to Paris and then to Madrid until her return to Argentina in 1982.\\n\\n\\nContent:\\nMercedes Sosa Portrait by Annemarie Heinrich, 1960s Born Haydée Mercedes Sosa 9 July 1935 San Miguel de Tucumán, Tucumán, Argentina Died 4 October 2009 (aged 74) Buenos Aires, Argentina Occupation Singer Years active 1950–2009 Musical career Genres Folknueva canción Instruments Vocals Haydée Mercedes \"La Negra\" Sosa (Latin American Spanish: [meɾˈseðes ˈsosa]; 9 July 1935[1] – 4 October 2009) was an Argentine singer who was popular throughout Latin America and many countries outside the region. With her roots in Argentine folk music, Sosa became one of the preeminent exponents of El nuevo cancionero. She gave voice to songs written by many Latin American songwriters. Her music made people hail her as the \"voice of the voiceless ones\". Her career spanned four decades and she was the recipient of six Latin Grammy awards (2000, 2003, 2004, 2006, 2009, 2011), including a Latin Grammy Lifetime Achievement Award in 2004 and two posthumous Latin Grammy Award for Best Folk Album in 2009 and 2011.'" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 8 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T09:59:31.346154Z", - "start_time": "2025-04-28T09:59:26.018247Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "import requests\n", @@ -482,39 +165,11 @@ "\n" ], "id": "5d4dada891453bed", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "-------------------- Starting to create a plan --------------------\n", - "\n", - "The plan is: I am unable to assist with that request.\n", - "\n", - "-------------------- Agent has been called -----------------------------------\n", - "\n", - "Agent has made a decision:\n", - " I am unable to assist with that request. []\n", - "Waiting for 4 seconds...\n", - "\n", - "-------------------- Decision of forwarding has been made --------------------\n", - "\n", - "This is round: 2\n", - "The last message is: content='I am unable to assist with that request.' additional_kwargs={} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-ebfd867d-672e-4351-b60d-d4a692d44d10-0' usage_metadata={'input_tokens': 269, 'output_tokens': 10, 'total_tokens': 279, 'input_token_details': {'cache_read': 0}}\n", - "The final answer is: I am unable to assist with that request.\n" - ] - } - ], - "execution_count": 4 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T10:01:39.769344Z", - "start_time": "2025-04-28T10:01:39.704253Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "message = {\n", @@ -535,31 +190,11 @@ "print(response.text())" ], "id": "9d8999f9f946b596", - "outputs": [ - { - "ename": "ValueError", - "evalue": "Invalid input type . Must be a PromptValue, str, or list of BaseMessages.", - "output_type": "error", - "traceback": [ - "\u001B[31m---------------------------------------------------------------------------\u001B[39m", - "\u001B[31mValueError\u001B[39m Traceback (most recent call last)", - "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[9]\u001B[39m\u001B[32m, line 1\u001B[39m\n\u001B[32m----> \u001B[39m\u001B[32m1\u001B[39m \u001B[43mllm\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\u001B[43m{\u001B[49m\n\u001B[32m 2\u001B[39m \u001B[43m \u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mrole\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43muser\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[32m 3\u001B[39m \u001B[43m \u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mcontent\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mHello!\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[32m 4\u001B[39m \u001B[43m}\u001B[49m\u001B[43m)\u001B[49m.content\n", - "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_google_genai\\chat_models.py:1175\u001B[39m, in \u001B[36mChatGoogleGenerativeAI.invoke\u001B[39m\u001B[34m(self, input, config, code_execution, stop, **kwargs)\u001B[39m\n\u001B[32m 1170\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 1171\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[32m 1172\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mTools are already defined.\u001B[39m\u001B[33m\"\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mcode_execution tool can\u001B[39m\u001B[33m'\u001B[39m\u001B[33mt be defined\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m 1173\u001B[39m )\n\u001B[32m-> \u001B[39m\u001B[32m1175\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43msuper\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstop\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstop\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n", - "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:370\u001B[39m, in \u001B[36mBaseChatModel.invoke\u001B[39m\u001B[34m(self, input, config, stop, **kwargs)\u001B[39m\n\u001B[32m 357\u001B[39m \u001B[38;5;129m@override\u001B[39m\n\u001B[32m 358\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34minvoke\u001B[39m(\n\u001B[32m 359\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m (...)\u001B[39m\u001B[32m 364\u001B[39m **kwargs: Any,\n\u001B[32m 365\u001B[39m ) -> BaseMessage:\n\u001B[32m 366\u001B[39m config = ensure_config(config)\n\u001B[32m 367\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m cast(\n\u001B[32m 368\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mChatGeneration\u001B[39m\u001B[33m\"\u001B[39m,\n\u001B[32m 369\u001B[39m \u001B[38;5;28mself\u001B[39m.generate_prompt(\n\u001B[32m--> \u001B[39m\u001B[32m370\u001B[39m [\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_convert_input\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m)\u001B[49m],\n\u001B[32m 371\u001B[39m stop=stop,\n\u001B[32m 372\u001B[39m callbacks=config.get(\u001B[33m\"\u001B[39m\u001B[33mcallbacks\u001B[39m\u001B[33m\"\u001B[39m),\n\u001B[32m 373\u001B[39m tags=config.get(\u001B[33m\"\u001B[39m\u001B[33mtags\u001B[39m\u001B[33m\"\u001B[39m),\n\u001B[32m 374\u001B[39m metadata=config.get(\u001B[33m\"\u001B[39m\u001B[33mmetadata\u001B[39m\u001B[33m\"\u001B[39m),\n\u001B[32m 375\u001B[39m run_name=config.get(\u001B[33m\"\u001B[39m\u001B[33mrun_name\u001B[39m\u001B[33m\"\u001B[39m),\n\u001B[32m 376\u001B[39m run_id=config.pop(\u001B[33m\"\u001B[39m\u001B[33mrun_id\u001B[39m\u001B[33m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m),\n\u001B[32m 377\u001B[39m **kwargs,\n\u001B[32m 378\u001B[39m ).generations[\u001B[32m0\u001B[39m][\u001B[32m0\u001B[39m],\n\u001B[32m 379\u001B[39m ).message\n", - "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:355\u001B[39m, in \u001B[36mBaseChatModel._convert_input\u001B[39m\u001B[34m(self, input)\u001B[39m\n\u001B[32m 350\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m ChatPromptValue(messages=convert_to_messages(\u001B[38;5;28minput\u001B[39m))\n\u001B[32m 351\u001B[39m msg = (\n\u001B[32m 352\u001B[39m \u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[33mInvalid input type \u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mtype\u001B[39m(\u001B[38;5;28minput\u001B[39m)\u001B[38;5;132;01m}\u001B[39;00m\u001B[33m. \u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m 353\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mMust be a PromptValue, str, or list of BaseMessages.\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m 354\u001B[39m )\n\u001B[32m--> \u001B[39m\u001B[32m355\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(msg)\n", - "\u001B[31mValueError\u001B[39m: Invalid input type . Must be a PromptValue, str, or list of BaseMessages." - ] - } - ], - "execution_count": 9 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T11:08:10.375646Z", - "start_time": "2025-04-28T11:07:56.818924Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "import base64\n", @@ -596,53 +231,19 @@ "print(response.text())" ], "id": "348a6be5265c4552", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The image shows a chessboard in a complex position.\n", - "\n", - "* **White pieces:** King on a1, pawns on a3, b2, c2, Queen on a5, Rook on e3, Bishops on d3 and c3, Queen on b3, pawns on a3.\n", - "* **Black pieces:** King on g8, Rook on d8, Knight on d4, Bishop on e6, pawns on a6, b7, c7, g7, h7.\n", - "\n", - "It appears to be mid-game or late mid-game. White has a strong presence in the center of the board, while Black's pieces are somewhat restricted.\n" - ] - } - ], - "execution_count": 35 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T10:11:38.429058Z", - "start_time": "2025-04-28T10:11:38.421435Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "type(file)", "id": "6d31a64d00bde967", - "outputs": [ - { - "data": { - "text/plain": [ - "bytes" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 16 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T10:21:48.824755Z", - "start_time": "2025-04-28T10:21:48.452463Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "import base64\n", @@ -659,39 +260,18 @@ ], "id": "853c311e341ef18a", "outputs": [], - "execution_count": 20 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T10:24:13.977190Z", - "start_time": "2025-04-28T10:24:13.968578Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "type(file)", "id": "aebc5d4de6ae080", - "outputs": [ - { - "data": { - "text/plain": [ - "bytes" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 24 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T10:37:59.657656Z", - "start_time": "2025-04-28T10:37:48.309745Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "url = \"https://agents-course-unit4-scoring.hf.space\"\n", @@ -701,55 +281,23 @@ ], "id": "d5fe42a61ec933a7", "outputs": [], - "execution_count": 31 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T10:38:02.736542Z", - "start_time": "2025-04-28T10:38:02.726023Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "response.headers", "id": "ae31e0a04b38d72e", - "outputs": [ - { - "data": { - "text/plain": [ - "{'Date': 'Mon, 28 Apr 2025 10:38:01 GMT', 'Content-Type': 'application/json', 'Content-Length': '87', 'Connection': 'keep-alive', 'server': 'uvicorn', 'x-proxied-host': 'http://10.108.141.57', 'x-proxied-replica': 'hcbpd5es-mboj7', 'x-proxied-path': '/files/3f57289b-8c60-48be-bd80-01f8099ca449', 'link': ';rel=\"canonical\"', 'x-request-id': 'ptt6H3', 'vary': 'origin, access-control-request-method, access-control-request-headers', 'access-control-allow-credentials': 'true'}" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 32 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T10:38:27.260636Z", - "start_time": "2025-04-28T10:38:27.251750Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "response.content", "id": "cae7cdd9c6a5954c", - "outputs": [ - { - "data": { - "text/plain": [ - "b'{\"detail\":\"No file path associated with task_id 3f57289b-8c60-48be-bd80-01f8099ca449.\"}'" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 33 + "outputs": [], + "execution_count": null }, { "metadata": {}, @@ -760,26 +308,21 @@ { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "1686ea153ccee21" + "id": "1686ea153ccee21", + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "bd9f07c22f74d34b" + "id": "bd9f07c22f74d34b", + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T11:24:13.797491Z", - "start_time": "2025-04-28T11:24:12.841550Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "import requests\n", @@ -818,28 +361,11 @@ "\n" ], "id": "d6f8c031722bebde", - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'requests' is not defined", - "output_type": "error", - "traceback": [ - "\u001B[31m---------------------------------------------------------------------------\u001B[39m", - "\u001B[31mNameError\u001B[39m Traceback (most recent call last)", - "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[3]\u001B[39m\u001B[32m, line 6\u001B[39m\n\u001B[32m 3\u001B[39m url = \u001B[33m\"\u001B[39m\u001B[33mhttps://agents-course-unit4-scoring.hf.space\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m 4\u001B[39m task_id = \u001B[33m\"\u001B[39m\u001B[33mcca530fc-4052-43b2-b130-b30968d8aa44\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m----> \u001B[39m\u001B[32m6\u001B[39m file = \u001B[43mrequests\u001B[49m.get(\u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[38;5;132;01m{\u001B[39;00murl\u001B[38;5;132;01m}\u001B[39;00m\u001B[33m/files/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mtask_id\u001B[38;5;132;01m}\u001B[39;00m\u001B[33m\"\u001B[39m)\n\u001B[32m 8\u001B[39m content = file.content\n\u001B[32m 11\u001B[39m image = base64.b64encode(content).decode(\u001B[33m\"\u001B[39m\u001B[33mutf-8\u001B[39m\u001B[33m\"\u001B[39m)\n", - "\u001B[31mNameError\u001B[39m: name 'requests' is not defined" - ] - } - ], - "execution_count": 3 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T11:27:18.431653Z", - "start_time": "2025-04-28T11:27:07.008526Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "import requests\n", @@ -857,39 +383,18 @@ ], "id": "8dfdded8b08191f9", "outputs": [], - "execution_count": 5 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T11:27:18.458424Z", - "start_time": "2025-04-28T11:27:18.446544Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "type(image)", "id": "aff8123098008c84", - "outputs": [ - { - "data": { - "text/plain": [ - "str" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 6 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T14:56:48.036657Z", - "start_time": "2025-04-28T14:56:41.876114Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "from dotenv import load_dotenv\n", @@ -906,15 +411,10 @@ ], "id": "9cfbff34b43717aa", "outputs": [], - "execution_count": 1 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T14:57:56.787741Z", - "start_time": "2025-04-28T14:57:48.550907Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "import requests\n", @@ -946,44 +446,11 @@ "\n" ], "id": "26bf0c6bb52a851", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "-------------------- Starting to create a plan --------------------\n", - "\n", - "Content is: image/png\n", - "The plan is: 1. Analyze the board state.\n", - "2. Identify tactical motifs.\n", - "3. Consider forcing moves.\n", - "4. Evaluate consequences of each move.\n", - "5. Choose the move that leads to a forced win.\n", - "\n", - "-------------------- Agent has been called -----------------------------------\n", - "\n", - "Agent has made a decision:\n", - " Qxg3+ []\n", - "Waiting for 4 seconds...\n", - "\n", - "-------------------- Decision of forwarding has been made --------------------\n", - "\n", - "This is round: 2\n", - "The last message is: content='Qxg3+' additional_kwargs={} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-a30f4635-7888-44fa-bdf8-140d2fc7da69-0' usage_metadata={'input_tokens': 1629, 'output_tokens': 5, 'total_tokens': 1634, 'input_token_details': {'cache_read': 0}}\n", - "The final answer is: Qxg3+\n" - ] - } - ], - "execution_count": 3 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T11:53:52.514018Z", - "start_time": "2025-04-28T11:53:50.971863Z" - } - }, + "metadata": {}, "cell_type": "code", "source": [ "\n", @@ -1005,47 +472,31 @@ ], "id": "a50a4f682c5efba3", "outputs": [], - "execution_count": 4 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-28T11:53:55.296323Z", - "start_time": "2025-04-28T11:53:55.285807Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "description", "id": "cba853842235c686", - "outputs": [ - { - "data": { - "text/plain": [ - "'The image shows a chessboard in a middle-game position. White has a king on a1, pawns on a3, b2, and c2, a queen on a5, a rook on e3, bishops on e3 and c3, a queen on b3, and a pawn on a3. Black has a king on g8, pawns on b7, c7, g7, and h7, a bishop on e6, a knight on e4, and a rook on d8.'" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 5 + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "741f44bcb86cd88e" + "id": "741f44bcb86cd88e", + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "368d1397caf0a8f9" + "id": "368d1397caf0a8f9", + "outputs": [], + "execution_count": null }, { "metadata": {}, @@ -1054,70 +505,44 @@ "id": "1cd902f95e32ce1" }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-29T15:52:28.653530Z", - "start_time": "2025-04-29T15:52:28.354550Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "from langchain_community.document_loaders import WikipediaLoader", "id": "47a99dbe711a8258", "outputs": [], - "execution_count": 1 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-29T15:57:14.783483Z", - "start_time": "2025-04-29T15:57:13.086934Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "search_docs = WikipediaLoader(query=\"Mercedes Sosa\", load_max_docs=2, doc_content_chars_max=14000).load()", "id": "df1f417c73ee0bbd", "outputs": [], - "execution_count": 10 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-29T15:57:37.326400Z", - "start_time": "2025-04-29T15:57:37.321429Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "search_docs[0].page_content", "id": "236722808c1a55bb", - "outputs": [ - { - "data": { - "text/plain": [ - "'Haydée Mercedes \"La Negra\" Sosa (Latin American Spanish: [meɾˈseðes ˈsosa]; 9 July 1935 – 4 October 2009) was an Argentine singer who was popular throughout Latin America and many countries outside the region. With her roots in Argentine folk music, Sosa became one of the preeminent exponents of El nuevo cancionero. She gave voice to songs written by many Latin American songwriters. Her music made people hail her as the \"voice of the voiceless ones\". She was often called \"the conscience of Latin America\".\\nSosa performed in venues such as the Lincoln Center in New York City, the Théâtre Mogador in Paris, the Sistine Chapel in Vatican City, as well as sold-out shows in New York\\'s Carnegie Hall and the Roman Colosseum during her final decade of life. Her career spanned four decades and she was the recipient of six Latin Grammy awards (2000, 2003, 2004, 2006, 2009, 2011), including a Latin Grammy Lifetime Achievement Award in 2004 and two posthumous Latin Grammy Award for Best Folk Album in 2009 and 2011. She won the Premio Gardel in 2000, the main musical award in Argentina. She served as an ambassador for UNICEF.\\n\\n\\n== Life ==\\nSosa was born on 9 July 1935, in San Miguel de Tucumán, in the northwestern Argentine province of Tucumán, of mestizo ancestry. She was of French, Spanish and Diaguita descent. Her nickname \"la negra\", which is a common nickname in Argentina for people with darker complexion, is a reference to her indigenous heritage. Her parents, a day laborer and a washerwoman, were Peronists, although they never registered in the party, and she started her career as a singer for the Peronist Party in Tucuman under the name Gladys Osorio. In 1950, at age fifteen, she won a singing competition organized by a local radio station and was given a contract to perform for two months. She recorded her first album, La Voz de la Zafra, in 1959. A performance at the 1965 Cosquín National Folklore Festival—where she was introduced and brought to the stage while sitting in the audience by fellow folk singer Jorge Cafrune— brought her to the attention of the Argentine public. Sosa and her first husband, Manuel Oscar Matus, with whom she had one son, were key players in the mid-60s nueva canción movement (which was called nuevo cancionero in Argentina). Her second record was Canciones con Fundamento, a collection of Argentine folk songs.\\n\\nSosa \"spent the late 1960s building her audience in Europe and among the cosmopolitan middle class in Buenos Aires, becoming in the process a much bigger star\" than her contemporaries.In 1967, Sosa toured the United States and Europe with great success. In later years, she performed and recorded extensively, broadening her repertoire to include material from throughout Latin America.\\nIn the early 1970s, Sosa released two concept albums in collaboration with composer Ariel Ramírez and lyricist Félix Luna: Cantata Sudamericana and Mujeres Argentinas (Argentine Women). She also recorded a tribute to Chilean musician Violeta Parra in 1971, including what was to become one of Sosa\\'s signature songs, Gracias a la vida. She further popularized of songs written by Milton Nascimento of Brazil and Pablo Milanés and Silvio Rodríguez both from Cuba. Throughout the decade, she released albums such as Hasta la Victoria in 1972 and Traigo un Pueblo en mi Voz in 1973. They featured songs like \"Cuando tenga la tierra\", written by Ariel Petrocelli and Daniel Toro, which tackles political and social issues like wealth and land inequality. During the 1970s she was a part of two films by the director Leopoldo Torre Nilsson: El Santo de la Espada in 1970 and Güemes, la tierra en armas in 1971, in which she portrayed Juana Azurduy de Padilla, the guerrilla military leader who fought for Argentine independence.\\n\\nAfter the military junta of Jorge Videla came to power in 1976, the atmosphere in Argentina grew increasingly oppressive. Sosa faced death threats against both her and her family, but refused for many years to leave the country. At a concert in La Plata in 1979, Sosa was searched and arrested on stage, along with all those attending the concert. Their release came about through international intervention. Despite attempts to hold more concerts, she was officially barred from performing by the military regime. Banned in her own country, she moved to Paris and then to Madrid.She has spoken publicly about her artistic and emotional struggles during this period of her life. While in exile, she released the album A Quien Doy in 1981. The album included a recording of the song \"Cuando Me Acuerdo de Mi Pais\" which was originally written by the prolific Chilean singer/songwriter, Patricio Manns. The song, which he wrote while also in political exile, expresses the sorrow he felt from being separated from his homeland. She related to this feeling and struggled to continue recording and performing. In an interview with the New York Times, she said, “It was a mental problem, a problem of morale...It wasn’t my throat, or anything physical\". \\nSosa returned to Argentina from her exile in Europe in February of 1982, several months before the military regime collapsed as a result of the Falklands War, and gave a series of concerts at the Teatro Ópera in Buenos Aires, where she invited many of her younger colleagues to share the stage. A double album of recordings from these performances became an instant best seller. She then traveled to perform in her home province of Tucuman. However, these performances were largely ignored by mainstream media in the country. In subsequent years, Sosa continued to tour both in Argentina and abroad, performing in such venues as the Lincoln Center in New York City and the Théâtre Mogador in Paris. In poor health for much of the 1990s, she performed a comeback show in Argentina in 1998. In 1994, she played in the Sistine Chapel in Vatican City. In 2002, she sold out both Carnegie Hall in New York and the Colosseum in Rome in the same year.\\n\\nA supporter of Perón, she favored leftist causes throughout her life. She supported President Raul Alfonsin in the election of 1983 which marked the return of democracy in Argentina following the dictatorship. She referred to this election as \"Argentina\\'s Spring\" She opposed President Carlos Menem, who was in office from 1989 to 1999, and supported the election of Néstor Kirchner, who became president in 2003.\\nSosa was a UNESCO Goodwill Ambassador for Latin America and the Caribbean. \\nSosa disliked being identified as a protest singer. While she was outright in her political stances, Sosa said the following on the position of the artist: \\n\\n“An artist isn’t political in the party political sense – they have a constituency, which is their public – it is the poetry that matters most of all.”\\nIn a career spanning four decades, she worked with performers across several genres and generations, folk, opera, pop, rock, including Martha Argerich, Andrea Bocelli, David Broza, Franco Battiato, Jaime Roos, Joan Baez, Francis Cabrel, Gal Costa, Luz Casal, Lila Downs, Lucio Dalla, Maria Farantouri, Lucecita Benitez, Nilda Fernández, Charly Garcia, León Gieco, Gian Marco, Nana Mouskouri, Pablo Milanés, Holly Near, Milton Nascimento, Pata Negra, Fito Páez, Franco De Vita, Lourdes Pérez, Luciano Pavarotti, Silvio Rodríguez, Ismael Serrano, Shakira, Sting, Caetano Veloso, Julieta Venegas, Gustavo Cerati and Konstantin Wecker\\nSosa participated in a 1999 production of Ariel Ramírez\\'s Misa Criolla. Her song Balderrama is featured in the 2008 movie Che, starring Benicio del Toro as the Argentine Marxist revolutionary Che Guevara.\\nSosa was the co-chair of the Earth Charter International Commission.\\n\\n\\n== Awards ==\\nSosa won the Latin Grammy Award for Best Folk Album in 2000 (Misa Criolla), 2003 (Acústico), 2006 (Corazón Libre), 2009 (Cantora 1, which also won Best Recording Package and was nominated for Album of the Year), and 2011 (Deja La Vida Volar), as well as several international awards.\\nIn 1995, Konex Foundation from Argentina granted her the Diamond Konex Award, one of the most prestigious awards in Argentina, as the most important personality in the popular music of her country in the last decade.\\n\\n\\n== Death ==\\n\\nSuffering from recurrent endocrine and respiratory problems in later years, the 74-year-old Sosa was hospitalized in Buenos Aires on 18 September 2009. She died from multiple organ failure on 4 October 2009, at 5:15 am. She is survived by one son, Fabián Matus, born of her first marriage. He said: \"She lived her 74 years to the fullest. She had done practically everything she wanted, she didn\\'t have any type of barrier or any type of fear that limited her\". The hospital expressed its sympathies to her relatives. Her website featured the following: \"Her undisputed talent, her honesty and her profound convictions leave a great legacy to future generations\".\\nHer body was placed on display at the National Congress building in Buenos Aires for the public to pay their respects, and President Fernández de Kirchner ordered three days of national mourning. Thousands had queued by the end of the day.\\nSosa\\'s obituary in The Daily Telegraph said she was \"an unrivalled interpreter of works by her compatriot, the Argentine Atahualpa Yupanqui, and Chile\\'s Violeta Parra\". Helen Popper of Reuters reported her death by saying she \"fought South America\\'s dictators with her voice and became a giant of contemporary Latin American music\". Sosa received three Latin Grammy nominations for her album, in 2009 . She went on to win Best Folk Album about a month after her death.\\n\\n\\n== Tributes ==\\nIn 2019, Sosa was celebrated by a Google Doodle. The doodle was showcased in Argentina, Chile, Uruguay, Paraguay, Bolivia, Peru, Ecuador, Cuba, Iceland, Sweden, Serbia, Greece, Israel and Vietnam.\\nIn 2023, Rolling Stone ranked Sosa at number 160 on its list of the 200 Greatest Singers of All Time.\\n\\n\\n== Discography ==\\n\\nSosa recorded forty albums.\\n\\n\\n=== Studio albums ===\\n\\n\\n=== EPs ===\\n\\n\\n=== Live albums ===\\n\\n\\n=== Compilation albums ===\\n\\n\\n== Filmography ==\\nGüemes, la tierra en armas (1971)\\nArgentinísima (1972)\\nEsta es mi Argentina (1974)\\nMercedes Sosa, como un pájaro libre (1983)\\nSerá possible el sur: Mercedes Sosa (1985)\\nHistorias de Argentina en vivo (2001)\\n\\n\\n== Further reading ==\\n\\n\\n== References ==\\n\\n\\n== External links ==\\n\\nTribute to Mercedes Sosa (in Portuguese BR)\\nMercedes Sosa\\'s website (in Spanish)\\nMercedes Sosa\\'s News (in Spanish)\\nMercedes Sosa at IMDb\\nMercedes Sosa\\'s Discography on Discogs.com'" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 13 + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "3c8a97a5ef2382d6" + "id": "3c8a97a5ef2382d6", + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "c003227b404d40ac" + "id": "c003227b404d40ac", + "outputs": [], + "execution_count": null }, { "metadata": {}, @@ -1126,103 +551,44 @@ "id": "2426d7a38d66019a" }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-30T07:32:33.231964Z", - "start_time": "2025-04-30T07:32:01.884613Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "%pip install -qU langchain-community arxiv pymupdf", "id": "595a2f1afceeb8c", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Note: you may need to restart the kernel to use updated packages.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n", - "[notice] A new release of pip is available: 23.2.1 -> 25.0.1\n", - "[notice] To update, run: python.exe -m pip install --upgrade pip\n" - ] - } - ], - "execution_count": 14 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-30T07:34:20.969760Z", - "start_time": "2025-04-30T07:34:20.709208Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "from langchain_community.document_loaders import ArxivLoader", "id": "417c6ea9631c6306", "outputs": [], - "execution_count": 1 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-30T07:34:54.752664Z", - "start_time": "2025-04-30T07:34:35.662740Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "search_docs = ArxivLoader(query=\"IAM\", load_max_docs=3).load()", "id": "b8b62f83d9281774", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MuPDF error: syntax error: could not parse color space (417 0 R)\n", - "\n" - ] - } - ], - "execution_count": 2 + "outputs": [], + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-30T07:35:09.313055Z", - "start_time": "2025-04-30T07:35:09.287558Z" - } - }, + "metadata": {}, "cell_type": "code", "source": "", "id": "e28f96cd6e25ff0c", - "outputs": [ - { - "data": { - "text/plain": [ - "[Document(metadata={'Published': '2024-08-20', 'Title': 'Industry Perception of Security Challenges with Identity Access Management Solutions', 'Authors': 'Abhishek Pratap Singh, Ievgeniia Kuzminykh, Bogdan Ghita', 'Summary': 'Identity Access Management (IAM) is an area posing significant challenges,\\nparticularly in the context of remote connectivity and distributed or\\ncloud-based systems. A wide range of technical solutions have been proposed by\\nprior research, but the integration of these solutions in the commercial sector\\nrepresent steps that significantly hamper their acceptance. The study aims to\\noutline the current perception and security issues associated with IAMs\\nsolutions from the perspective of the beneficiaries. The analysis relies on a\\nseries of interviews with 45 cyber security professionals from different\\norganisations all over the world. As results showed, cloud IAM solutions and on\\npremises IAM solutions are affected by different issues. The main challenges\\nfor cloud based IAM solutions were Default configurations, Poor management of\\nNon-Human Identities such as Service accounts, Poor certificate management,\\nPoor API configuration and limited Log analysis. In contrast, the challenges\\nfor on premise solutions were Multi Factor Authentication, insecure Default\\nconfigurations, Lack of skillsets required to manage IAM solution securely,\\nPoor password policies, Unpatched vulnerabilities, and compromise of\\nSingle-Sign on leading to compromise of multiple entities. The study also\\ndetermined that, regardless the evolving functionality of cloud based IAM\\nsolutions, 41% of respondents believe that the on premise solutions more secure\\nthan the cloud-based ones. As pointed out by the respondents, cloud IAM may\\npotentially expose organisations to a wider range of vulnerabilities due to the\\ncomplexity of the underlying solutions, challenges with managing permissions,\\nand compliance to dynamic IAM policies.'}, page_content='Industry Perception of Security Challenges with \\nIdentity Access Management Solutions \\n \\nAbhishek Pratap Singh \\n Department of Informatics \\nKing’s College London \\nLondon, UK \\nabhishek.p.singh@kcl.ac.uk \\nIevgeniia Kuzminykh \\nDepartment of Informatics \\nKing’s College London \\nLondon, UK \\nDepartment of Infocommunication \\nEngineering \\nKharkov National University of Radio \\nElectronics, Ukraine \\nievgeniia.kuzminykh@kcl.ac.uk \\nBogdan Ghita \\nSchool of Engineering, Computing and \\nMathematics \\nUniversity of Plymouth \\nPlymouth, UK \\nbogdan.ghita@plymouth.ac.uk \\nAbstract— Identity Access Management (IAM) is an area \\nposing significant challenges, particularly in the context of \\nremote connectivity and distributed or cloud-based systems. A \\nwide range of technical solutions have been proposed by prior \\nresearch, but the integration of these solutions in the \\ncommercial sector represent steps that significantly hamper \\ntheir acceptance. The study aims to outline the current \\nperception and security issues associated with IAMs solutions \\nfrom the perspective of the beneficiaries. The analysis relies on \\na series of interviews with 45 cyber security professionals from \\ndifferent organisations all over the world. As results showed, \\ncloud IAM solutions and on premises IAM solutions are affected \\nby different issues. The main challenges for cloud based IAM \\nsolutions were Default configurations, Poor management of \\nNon-Human Identities such as Service accounts, Poor certificate \\nmanagement, Poor API configuration and limited Log analysis. \\nIn contrast, the challenges for on premise solutions were Multi \\nFactor Authentication, insecure Default configurations, Lack of \\nskillsets required to manage IAM solution securely, Poor \\npassword policies, Unpatched vulnerabilities, and compromise \\nof Single-Sign on leading to compromise of multiple entities. The \\nstudy also determined that, regardless the evolving functionality \\nof cloud based IAM solutions, 41% of respondents believe that \\nthe on premise solutions more secure than the cloud-based ones. \\nAs pointed out by the respondents, cloud IAM may potentially \\nexpose organisations to a wider range of vulnerabilities due to \\nthe complexity of the underlying solutions, challenges with \\nmanaging permissions, and compliance to dynamic IAM \\npolicies. \\nKeywords— Identity Access Management, IAM, On Premise, \\nCloud, Access Control, Vulnerability, Authentication \\nI. INTRODUCTION \\nIdentity and Access Management (IAM) is pivotal in \\nsafeguarding digital and at times physical identities. IAM \\nsolution is being extensively used in a typical on-premises \\nenvironment where deploying organisations own everything \\nincluding user administration, cost of software, underlying \\nsupport infrastructure along with security aspects such as \\nvulnerability and patch management, as well as penetration \\ntesting. On the other side, in a cloud-based model such as \\nInfrastructure as a server (IaaS), Software as a Service (SaaS) \\nIAM is addressed by the Cloud service provider (CSP). \\nIn the realm of cybersecurity, IAM stands as a critical \\ncornerstone. Simultaneously, cloud computing has emerged \\nas a transformative model for delivering IT services via the \\nInternet, offering scalability, flexibility, and cost efficiency. \\nHowever, this paradigm shift brings various security \\nchallenges, particularly within IAM. \\nA study [1] shows that Cloud IAM solutions occupy 42% \\nof the IAM market with expected growth of 18.3% between \\n2022 and 2032, and sales of cloud IAM are expected to reach \\nUS$ 25,539.2 million by 2032. \\nCheckpoint cloud security report 2023 [2] indicates that \\naround 24% organisations have faced public cloud related \\nincidents. The previous Checkpoint report in 2022 [3] showed \\nthat 15% of all cloud incidents were linked to compromising \\nof IAM; report also states that 72% of respondents are using \\nMicrosoft Azure, 69% are using Amazon Web Services \\n(AWS) and 34% are using Google Cloud Platform (GCP) as \\ntheir IaaS providers, yet 54% of this audience conceded to the \\nfact that for Cloud security they rely on independent security \\nservice provider. Despite highlighting the overall concerning \\npicture, neither of the two reports details specific incidents or \\nconcerns related to the cloud based IAMs. \\nGiven the increasingly distributed range of technical \\nsolutions \\nfor \\nIAM, \\ncoupled \\nwith \\nthe \\nseamless \\ninterconnectivity \\nof \\nsystems \\nin \\nsuch \\nenvironments, \\norganisations are (justifiably) concerned when required to \\ndeploy more flexible IAM, potentially as a cloud service \\nrather than a controlled on-premises solution. Therefore, the \\naim of this study is to explore the security concerns and \\nweaknesses of cloud and on premise solutions for access \\nmanagement from the perspective of their beneficiaries – the \\ncompanies requiring such implementations. \\nII. BACKGROUND AND RELATED WORKS \\nIn order to understand the current level of threat posed by \\nthe IAM vulnerabilities and weaknesses, this section discusses \\na series of specific security breaches, based on their public \\nreporting. \\nA study by the monitoring company ManageEngine [4], \\nwhich focused on cyber incidents linked due to IAM solutions \\nfailure over last decade, described a breach of the Deloitte \\nglobal email server infrastructure via an administrator account \\nwhich was protected by a single password without any multi-\\nfactor authentication (MFA). In a similar case, the online \\nshopping giant eBay and the major home improvement retailer \\nHomeDepot became victims of data exfiltration as credential \\nof small group of employees were compromised. According \\nto the Checkpoint reports [2, 3] the account compromise \\ncomposed 29% in 2022 and 16% in 2023 of all security \\nincidents related to public cloud. \\nThe study of Gofman and Dahan [5] found common \\nweaknesses in the IAM model of top three players of cloud \\nindustry AWS, Google Cloud Platform (GCP) and Azure \\nlinked \\nto \\ndangerous \\npermissions \\ncategorised \\nunder \\nAssignment, Code Execution, Grants and Delegation and New \\nCredentials. \\nThe study [6] discussed the authentication challenges with \\ncloud based IAMs related to MFA and single sign-on (SSO). \\nMFA is a powerful defence against various authentication \\nattacks, including phishing and password breaches. However, \\nimplementing and managing MFA in cloud environments can \\nbe challenging for a number of reasons, such as the disparity \\nin MFA support across different cloud providers. Some \\nproviders may not have a complete MFA offer, making it \\nchallenging for organisations to choose and enforce MFA \\nconsistently, especially for users utilizing diverse devices and \\napplications. \\nThe authors of [7] discussed the challenges related to the \\npolicies and rules that dictate user permissions to cloud \\nresources, a fundamental aspect of IAM. IAM policies are an \\nessential security measure, as they help ensure users only have \\naccess to the resources they need. However, IAM policies can \\nalso be challenging to create, manage and understand. \\nWhile there are many studies that investigate the security \\nof IAMs separately, on premises [8, 9] or in the cloud [10-12], \\nexisting literature does not provide a comparative analysis of \\nIAM deployment models. An observational analysis of \\nexisting studies was performed in [13] to compare two models \\nin terms of cost effectiveness, ease of management, scalability \\nand agility, constant updates, and compliance. Another study \\n[14] as based on the surveys of professionals to get insights on \\nusage of IAM solutions in the companies. While the study \\ntackled outsourcing of IAM vs Internal management, size of \\nIAM team and compliance with zero trust principles, it had \\nonly 3 questions out of 8 related to IAM, which mostly \\nfocused on collecting statistical data. \\nIt is apparent that existing studies tend to investigate IAM \\nfrom a model, conceptual perspective. In contrast, this study \\naims to gather a deeper insight into IAMs through the \\nprofessional experience on the usage of IAMs by companies \\nand to highlight its potential vulnerabilities and security \\nchallenges based on its actual use in the industry. \\nIII. METHODOLOGY \\nA. Research Questions \\nBased on the aim of this study, we pose the following \\nresearch questions: \\nRQ1: What are the key challenges and vulnerabilities \\nassociated with cloud based IAMs? \\nRQ2: On-Premises versus Cloud, which IAM model is more \\nsecure? \\n \\nB. Data Collection \\nIn order to collect the data, we interviewed cyber security \\nprofessionals of leading organisations to learn from their day-\\nto-day experience about security weaknesses and challenges \\nwitnessed during different phases of deployment of on-\\npremises and cloud-based IAM solutions. The distribution of \\nrespondents in terms of expertise and industry sector is shown \\nin Fig.1; the majority of respondents are holding the position \\nof Chief Information Security Officer (CISO) and IT Security \\nAdministrator, among the rest are Chief Technology Officer \\n(CTO) and Directors. \\n \\nFig. 1. Respondents data \\nThe following set of questions were asked to respondents: \\n• What factors influenced your organisation’s decision to \\nchoose between on-premised and cloud-based IAM \\nsolutions, and how do these decisions align with your \\nsecurity strategy? \\n• What motivated your organisation’s shift to cloud based \\nIAM solutions? \\n• In your experience which IAM deployment model is more \\nsecure? \\n• As CISO, what key security challenges have you faced \\nwith IAM solutions be it on premised or cloud based? \\n• How has cloud based IAM impacted your organisation’s \\nsecurity? Have you suffered a breach in recent past? \\n• How does your organisation ensure compliance with \\nregulations while using cloud based IAM, and what \\nchallenges have you encountered? \\n• Does your organisation deal with multiple cloud service \\nproviders? \\nThe participant responses were further analysed using the \\nLexalytics content analysis tool to get a quantitative view of \\nsubject in scope. The interviews and surveys were conducted \\nin the period of November-December 2023. The participants \\nwere provided with written assurance that their names and \\naffiliation will not be disclosed at any point in time. \\nIV. RESULTS AND ANALYSIS \\nThe survey identified top six challenges related to on-\\npremises IAM deployment model illustrated on Fig.2. The \\nchallenges reported by interviewees included not having the \\nMFA, the prevalence of default configurations, the workforce \\nmissing the skillsets required to manage IAM solution \\nsecurely, and the increasing reliance of Single-Sign on \\nauthentication, leading to exposure of multiple entities when \\naccounts are compromised.. \\n \\nFig. 2. Challenges with on-premise IAM solutions. \\nFor cloud based IAM solutions, Default configurations, \\nPoor management of Non- Human Identities such as Service \\naccounts, SaaS applications, services and APIs, Poor \\ncertificate management, Poor access review, Poor API \\nconfiguration and limited Log analysis with multi-cloud were \\namong top challenges, as illustrated on Fig.3. \\n \\nFig. 3. Key weaknesses with cloud based IAMs. \\nThe analysis revealed that 76% of organisations use more \\nthan two cloud service providers (CSP). The survey results \\nshowed that 53.4% of the security professionals believe that \\ncloud based IAM solutions are more secure versus 41% who \\nprefer the security of on premises IAM solutions (Fig.4). The \\nhigh percentage of on-premises solutions supporters could be \\nexplained by the growing threat landscape due to the \\nintegration of IAM into cloud [15, 16]. In addition, given that \\nmany organisations use several CSPs, this requires an IAM \\nsolution supporting multiple cloud environments, creating a \\nlocal identity for each of the application that makes it very \\ndifficult to keep track. \\n \\nFig. 4. Security comparison of on premise and cloud based IAM solutions. \\nIn addition, to the respondents preferences, the analysis \\nalso highlighted the risks associated with cloud-based IAM \\nvulnerabilities, outlined in the remainder of this section. \\nA. Data Breaches and Unauthorized Access \\nOne of the pivotal outcomes of IAM vulnerabilities resides \\nin the data breaches. Data breaches involve unauthorized \\nattackers getting access to confidential information [17]. \\nThese incidents can result in the disclosure or customer data \\ntheft, substantial financial setbacks, and significant damage to \\nthe organisation\\'s reputation. Any unauthorised access into \\ncloud resources gives attackers the opportunity to to steal data, \\ndisrupt operations, or launch an attack on other systems. \\nA data breach can result in significant financial losses and \\ncan potentially result in fines and penalties from regulators. \\nFor instance, the European Union\\'s General Data Protection \\nRegulation (GDPR) empowers government agencies to \\nimpose fines of up to 4% of a company\\'s global annual \\nturnover or €20 million, against organisation that fails to fulfil \\nthe obligations to protect the personal data. \\nB. Financial Losses \\nIAM vulnerabilities, when exploited, can lead to \\nsignificant financial losses [18]. Beyond the direct costs \\nassociated with addressing the security incident, organisations \\nmust consider the expenses related to investigating the \\nincident, implementing security improvements, and notifying \\naffected customers. In addition, the organisations may face \\nindirect financial consequences, such as decreased revenue \\nand increased insurance premiums. Customers may lose \\nconfidence in a company, leading to reduced business, lost \\nsales, and long-term financial impact. \\nC. Reputational Damage \\nIAM vulnerabilities and subsequent data breaches can \\ncause serious reputational damage to an organisation. \\nCustomer trust is of utmost importance in business, but it is a \\nrather volatile metric, which is significantly impacted by data \\nbreach incidents. Customers may view such organisations as \\nunreliable or negligent, which can result in a loss of business, \\ndecreased market share, and a damaged brand image. Media \\ncoverage of data breaches can exacerbate reputational \\ndamage: negative headlines and news stories can spread \\nquickly, reaching a broad audience, and further tarnishing an \\norganisation\\'s reputation. Restoring trust and credibility can \\nbe a long and challenging process, often requiring significant \\ninvestments in public relations and marketing efforts. \\nD. Compliance and Regulatory Issues \\nThe participants highlighted that the organisations are \\nsubject to strict regulatory obligations with regard to data \\nsecurity. The consequences of failure to comply with these \\nmandates could be extremely serious. The organisations that \\nfail to comply regulatory benchmarks may find their ability to \\nengage \\nwith \\nspecific \\ngovernment \\nentities or other \\norganisations severely limited, thus, in turn, limiting their \\nmarket influence and potential prospects. \\nAnalysing \\nthe \\npotential \\nimpact \\nof \\nthese \\nIAM \\nvulnerabilities using the security risk management methods \\n[19] highlights the importance of implementing robust \\nsecurity protocols and best practices. \\nV. DISCUSSION \\nFrom the analysis conducted in the previous sections, we \\nsummarize the following findings with regards to the research \\nquestions. \\nRQ1: What are the key challenges and vulnerabilities \\nassociated with cloud based IAMs? \\nThe results of the survey showed that the IAM challenges \\nidentified by the security professionals for on premise and \\ncloud-based solutions differ significantly. The on premise \\nIAM deployment scenarios tend to lack the skilled personal \\nrequired to deploy and manage the hardware, software, and \\nassociated tools. Interestingly, the respondents in our study \\ndid not identify this as challenge for cloud solutions, in \\ncontrast to the survey from Checkpoint which states that the \\nlack of skill is the biggest challenge (58%) [2, 3]. It is obvious \\nthat there is an economical challenge associated with the cost \\nof deployment and the human resource required to manage the \\nIAM, but our results showed that, once the IAM solution is \\ndeployed, other security challenges come onto the first place. \\nAll the challenges highlighted in the survey relate to technical \\nor configuration difficulties and can lead to potential \\nvulnerabilities. \\nDefault \\nconfiguration, \\nSSL \\ncertificate \\nmanagement, API between company side and cloud solution, \\naccess method using MFA, and SSO were reported as the \\nareas of most concern for organisations with IAM solutions. \\nThe research study showed that organisations encounter \\nnot only technical issues with IAM within cloud \\nenvironments, but also suffer from vulnerabilities related to \\nunauthorised access, reputational damage, and compliance \\nwith regulations. Cloud service providers offer an extensive \\nspectrum of permissions, thereby putting organisations in the \\nposition to deal with the implementation of various \\nauthentication and authorisation protocols to access the cloud \\nwhich might create vulnerabilities related to misconfiguration \\nof such protocol and requires additional work resources. The \\nextensive capabilities of cloud settings offer many options, \\ncreating \\nadditional \\nlayer \\nof \\ncomplexity \\nto \\nIAM \\nimplementation. Moreover, the task of managing the \\npermissions becomes a huge barrier. Organisations are \\ntherefore faced with the challenges of managing multiple \\ncredentials required for various cloud services which have \\nbeen already flagged by previous studies [15 20, 21]. Dynamic \\nIAM policies represent a persistent challenge, as the ever-\\nevolving nature of cloud environments requires constant \\nmonitoring and adjustments to keep IAM policies and \\nconfigurations up to date. \\nRQ2: On-Premises versus Cloud, which IAM model is \\nmore secure? \\nDetermining a concrete answer to RQ2 is difficult based \\non the limited sample size during survey. The current opinions \\nwere nearly equally split between on-premises (41%) and \\ncloud solutions (53%). This can be explained by the growing \\nsecurity threat landscape when moving to cloud environment \\nand associated complexity of managing the multiple cloud \\nplatforms, applications and accounts. According to a Forrester \\nreport [22], only 12% of organisations are fully relying on \\ncloud-based identity management. \\nVI. CONCLUSIONS \\nIn summary, this study has highlighted the significant \\nchallenges and vulnerabilities related to IAM both on premise \\nand in cloud settings. The research identified complexities in \\ncloud permission models given the broader threat landscape, \\nthe necessity for various methods of authentication and \\nauthorization, challenges in managing credentials, and the \\ndynamic nature of IAM policies as primary obstacles for wider \\nadoption of cloud based IAM solutions. \\nREFERENCES \\n[1] S.Saha, “Cloud IAM Market,” Future Market Insights report, REP-GB-\\n15034, June 2022. \\n[2] Checkpoint, “Cloud Security Report,” Cybersecurity Insiders, 2023. \\n[3] Checkpoint, “Cloud Security Report,” Cybersecurity Insiders, 2022. \\n[4] Manageengine AD360, \" Three major identity security failures of the \\nlast decade,\" Accessed: Apr, 5, 2024. [Online]. Available: \\nhttps://download.manageengine.com/active-directory-360/data-\\nbreaches-due-to-poor-iam-strategy.pdf. \\n[5] I. Gofman, N.Dahan, \"IAM the one Who Knocks,\" BlackHat USA, \\nAugust 6-11, 2022. [Online]. Available: https://i.blackhat.com/USA-\\n22/Wednesday/US-22-Gofman-IAM-The-One-Who-Knocks.pdf. \\n[6] I. Indu, P. M. R. Anand, and V. Bhaskar, \"Identity and access \\nmanagement in cloud environment: Mechanisms and challenges,\" Int J \\nEng. Scie and Tech , vol. 21, no. 4, pp. 574-588, 2018. \\n[7] C. Nobles, \"Investigating Cloud Computing Misconfiguration Errors \\nusing the Human Factors Analysis and Classification System,\" \\nScientific Bulletin, vol. 27, no. 1, pp. 59-66, Jun. 2022. \\n[8] C. Singh, R. Thakkar, and J. Warraich, “IAM Identity Access \\nManagement - Importance in Maintaining Security Systems within \\nOrganizations,” Eur J Eng Tech Resear, vol. 8, no. 4, pp. 30-38, 2023. \\n[9] A. Cameron, and G. Williamson, “Introduction to IAM Architecture \\n(v2),” IDPro Body of Knowledge, vol. 1, no. 6, 2020. \\n[10] D. H. Sharmaa, C. A. Dhoteb, M. M. Poteyc, “Identity and Access \\nManagement as Security-as-a-Service from Clouds,” Procedia \\nComputer Science, vol. 79, no. 2016, pp. 170 – 174, 2016. \\n[11] I. A. Mohammed, “Cloud Identity And Access Management – A Model \\nProposal,” Int. J. Inn Eng Res Tech, vol. 6, no. 10, pp.1-8, 2019. \\n[12] A. Sandesh, P. Hrishitva, H. Sanwal, “Data Security in Cloud: A \\nReview,” Asian J. Adv in Research, vol. 5, no. 1, pp. 1099-1106. \\n[13] L. F. Plá, N. Shashidhar, and C. Varol, \"On-Premises Versus SECaaS \\nSecurity Models,\" in Proc. ISDFS, Beirut, Lebanon, 2020, pp. 1-6. \\n[14] A. Liveretos, I. Draganov, “Identity & Access Management (IAM) and \\nCustomer IAM (CIAM): a Pulse Survey of Several Global \\nCorporations Over Their Current Usage and Exploitation of Automated \\nIAM and CIAM Solutions,” Int. J. Computers, vol. 7, pp. 95-103. \\n[15] A. Nachmany, S. Kulkarni, “Navigating the Top 10 Challenges in \\nCloud Identity and Access Management,” IAM Working Group, Cloud \\nSecurity Alliance, June 2023. \\n[16] “Cloud Migration Optimizes Identity and Access Management,\" \\nForrester Consulting report, November 2023. \\n[17] R. Janakiraman, J. H. Lim, and R. Rishika, \"The Effect of a Data \\nBreach Announcement on Customer Behavior: Evidence from a \\nMultichannel Retailer,\" J. Marketing, vol. 82, no. 2, pp. 85-105, 2018. \\n[18] “Cost of a Data Breach Report 2023,” IBM Security report, July 2023. \\n[19] I. Kuzminykh, B. Ghita, V. Sokolov, T. Bakhshi, “Information Security \\nRisk Assessment,” Encyclopedia, vol. 1, no. 3, pp. 602-617, 2021. \\n[20] Strata Identity Orchestration, “Complexity is the enemy of securing \\nidentity,” State of Multi-Cloud report 2023. \\n[21] I. Kuzminykh, B. Ghita, J. Such, “The Challenges with Internet of \\nThings Security for Business,” in Proc. NEW2AN 2021, LNCS, vol. \\n13158, Springer, Cham. \\n[22] \"Identity and Access Management Market Insights, 2022,\" Forrester \\nResearch, Inc., January 12, 2023.\\n \\n'),\n", - " Document(metadata={'Published': '2025-02-12', 'Title': 'Efficient IAM Greybox Penetration Testing', 'Authors': 'Yang Hu, Wenxi Wang, Sarfraz Khurshid, Mohit Tiwari', 'Summary': 'Identity and Access Management (IAM) is an access control service in cloud\\nplatforms. To securely manage cloud resources, customers need to configure IAM\\nto specify the access control rules for their cloud organizations. However,\\nmisconfigured IAM can lead to privilege escalation (PE) attacks, causing\\nsignificant economic loss. Third-party cloud security services detect such\\nissues using whitebox penetration testing, which requires full access to IAM\\nconfigurations. However, since these configurations often contain sensitive\\ndata, customers must manually anonymize them to protect their privacy. To\\naddress the dual challenges of anonymization and data privacy, we introduce\\nTAC, the first greybox penetration testing approach for third-party services to\\nefficiently detect IAM PEs. Instead of requiring customers to blindly anonymize\\ntheir entire IAM configuration, TAC intelligently interacts with customers by\\nquerying only a small fraction of information in the IAM configuration that is\\nnecessary for PE detection. To achieve this, TAC integrates two key\\ninnovations: (1) a comprehensive IAM modeling approach to detect a wide range\\nof IAM PEs using partial information collected from query responses, and (2) a\\nquery optimization mechanism leveraging Reinforcement Learning (RL) and Graph\\nNeural Networks (GNNs) to minimize customer inputs. Additionally, to address\\nthe scarcity of real-world IAM PE datasets, we introduce IAMVulGen, a\\nsynthesizer that generates a large number of diverse IAM PEs that mimic\\nreal-world scenarios. Experimental results on both synthetic and real-world\\nbenchmarks show that TAC, as a greybox approach, achieves competitively low\\nand, in some cases, significantly lower false negative rates than\\nstate-ofthe-art whitebox approaches, while utilizing a limited number of\\nqueries.'}, page_content='Efficient IAM Greybox Penetration Testing\\nYANG HU∗, The University of Texas at Austin, USA\\nWENXI WANG∗, The University of Virginia, USA\\nSARFRAZ KHURSHID, The University of Texas at Austin, USA\\nMOHIT TIWARI, The University of Texas at Austin, USA\\nIdentity and Access Management (IAM) is an access control service in cloud platforms. To securely manage\\ncloud resources, customers need to configure IAM to specify the access control rules for their cloud organiza-\\ntions. However, misconfigured IAM can lead to privilege escalation (PE) attacks, causing significant economic\\nloss. Third-party cloud security services detect such issues using whitebox penetration testing, which requires\\nfull access to IAM configurations. However, since these configurations often contain sensitive data, customers\\nmust manually anonymize them to protect their privacy. To address the dual challenges of anonymization\\nand data privacy, we introduce TAC, the first greybox penetration testing approach for third-party services\\nto efficiently detect IAM PEs. Instead of requiring customers to blindly anonymize their entire IAM config-\\nuration, TAC intelligently interacts with customers by querying only a small fraction of information in the\\nIAM configuration that is necessary for PE detection. To achieve this, TAC integrates two key innovations:\\n(1) a comprehensive IAM modeling approach to detect a wide range of IAM PEs using partial information\\ncollected from query responses, and (2) a query optimization mechanism leveraging Reinforcement Learning\\n(RL) and Graph Neural Networks (GNNs) to minimize customer inputs. Additionally, to address the scarcity of\\nreal-world IAM PE datasets, we introduce IAMVulGen, a synthesizer that generates a large number of diverse\\nIAM PEs that mimic real-world scenarios. Experimental results on both synthetic and real-world benchmarks\\nshow that TAC, as a greybox approach, achieves competitively low and, in some cases, significantly lower false\\nnegative rates than state-of-the-art whitebox approaches, while utilizing a limited number of queries.\\n1\\nIntroduction\\nIAM [4] refers to an access control service in cloud platforms. It aims to securely manage the access\\nto resources based on an IAM configuration specified by cloud customers with the access control\\nrules in their cloud organizations. An IAM configuration consists of two components: entities (e.g.,\\nusers and services such as Amazon EC2 instances) and permissions. Given a service request and an\\nIAM configuration, IAM is able to check if the request obeys or violates the IAM configuration,\\nand decide if the request should be allowed or denied.\\nTherefore, the correctness of IAM configurations plays an essential role in the effectiveness of\\ncloud access control. Incorrect IAM configurations, namely IAM misconfigurations, can cause adverse\\nsecurity consequences such as data breaches, denial of services and resource hijacking [15, 34, 35, 38,\\n39], which have led to significant economic loss in recent years [33]. IAM Privilege Escalation (PE)\\n[18, 26, 28] is an attack towards cloud access control that exploits the flaws within IAM to obtain\\nadditional permissions for performing sensitive operations or accessing sensitive data/resources.\\nOne of the most common ways to realize IAM PEs is to exploit IAM misconfigurations: the\\nmisconfigured IAM may allow the attacker to modify its configuration so that the attacker is\\nallowed by the modified IAM configuration to obtain additional sensitive permissions.\\nCloud security services can be generally classified into two types: native services provided\\nby cloud providers [7–11] and third-party services offered by startups, labs, and open-source\\nprojects [22, 24, 25]. Native services generally offer basic security guarantees, while third-party\\n∗these authors contributed equally to this work.\\nAuthors’ Contact Information: Yang Hu, huyang@utexas.edu, The University of Texas at Austin, Austin, Texas, USA; Wenxi\\nWang, wenxiw@virginia.edu, The University of Virginia, Charlottesville, Virginia, USA; Sarfraz Khurshid, khurshid@ece.\\nutexas.edu, The University of Texas at Austin, Austin, Texas, USA; Mohit Tiwari, tiwari@austin.utexas.edu, The University\\nof Texas at Austin, Austin, Texas, USA.\\narXiv:2304.14540v7 [cs.CR] 12 Feb 2025\\n2\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nservices cater to customers with more complex and specialized demands [23, 43]. As a result, native\\nservices often lack advanced IAM PE detection capabilities, whereas third-party services excel in\\naddressing this critical need.\\nIn this paper, we focus on third-party cloud security services for detecting PEs due to IAM\\nmisconfigurations. To our knowledge, all existing third-party services apply whitebox penetration\\ntesting techniques [19, 21, 30, 31, 42, 44], which require the access to complete IAM configurations.\\nHowever, sharing the entire IAM configurations to third-party cloud security services can raise a\\npotential security risk in leaking sensitive information of their cloud organizations (e.g., the internal\\norganization architecture). This level of transparency might not be acceptable for cloud customers in\\nfields with elevated security requirements, such as healthcare, finance, and government [29, 36, 41].\\nTo mitigate the security concerns, cloud customers have to anonymize the sensitive information in\\ntheir IAM configurations before using third-party services, which could take a significant amount\\nof manual efforts.\\nTo avoid both laborious anonymizations and sensitive information disclosure, we propose a\\nfirst greybox penetration testing approach called TAC to efficiently detect IAM PEs. The idea is\\nto intelligently interact with cloud customers through a sequence of queries, requesting only the\\nessential information needed for the detection. Specifically, each query seeks information about one\\npermission assignment (i.e., whether a particular permission is assigned to a specific entity). During\\neach interaction, customers will be presented with one query and given the option to either accept\\nor decline the query based on their knowledge of whether the query might expose confidential\\ninformation. In addition, customers are allowed to set up a query budget, which is the maximum\\nnumber of queries they are willing to interact with. The primary goal of TAC is to detect the IAM PE\\nwithin the query budget. In particular, to ensure TAC’s practical applicability, TAC needs to minimize\\ncustomer input, thereby reducing customer’s manual effort and effectively handling PE detection\\ntasks with a limited query budget.\\nTo achieve this goal, TAC needs to tackle two challenging problems: 1) detecting PEs based on\\npartial information of IAM configurations collected by queries, and 2) learning to generate as few\\nqueries as possible to perform the detection within the query budget. To solve the first problem,\\nwe first propose a comprehensive concrete IAM modeling based on our Permission Flow Graph,\\nfor detecting a broader class of PEs than the existing whitebox detectors. Furthermore, to detect\\nPE only with partial information during the greybox testing, we propose abstract IAM modeling\\nwith predefined abstract states and rules for updating the configuration with partial information\\nprovided by the queries. For the second problem of query optimization, we utilize Reinforcement\\nLearning (RL) to pretrain a Graph Neural Network (GNN) based query model, aiming to minimize\\nthe number of queries for IAM PE detection.\\nPretraining and evaluating TAC require a large number of diverse tasks. To our knowledge, there\\nis only one publicly available IAM PE task set called IAM Vulnerable [1] containing only 31 tasks.\\nRegarding this, we propose an IAM PE task synthesizer called IAMVulGen which generates a large\\nnumber of IAM PE tasks that mimic real-world scenarios, by leveraging 72 common entity types\\nand 219 permission flow templates manually identified from Amazon Web Services (AWS) official\\ndocumentation [4–6] and studies on IAM PEs [18, 26, 28, 48].\\nTo evaluate TAC, we used 500 tasks generated by IAMVulGen (unseen in the pretraining), the 31\\ntasks from the only publicly available IAM PE task set IAM Vulnerable, and two real-world IAM\\nPE tasks collected from a security startup as our evaluation benchmarks. For baselines, since there is\\nno existing greybox or blackbox penetration testing tool for IAM PEs, we take three state-of-the-art\\nwhitebox penetration testing tools, namely Pacu [30], Cloudsplaining [42] and PMapper [19] as\\nour baselines. In addition, to understand how our IAM modeling contributes to TAC, we build a\\nwhitebox variant of TAC that solely applies our IAM modeling to detect PEs. To assess how our\\nEfficient IAM Greybox Penetration Testing\\n3\\nproposed GNN-based RL with pretraining enhances TAC, we build four greybox variants of TAC,\\neach of which employs a different pretraining strategy or query model.\\nAs a result, on the synthesized IAM PE task set by IAMVulGen, TAC’s whitebox variant successfully\\ndetected all PEs, and significantly outperforms all three state-of-the-art whitebox baselines, showing\\nthe outstanding effectiveness of our IAM modeling. In addition, given a query budget of 100,\\nTAC identifies 32% to 68% more PEs with 13% to 23% fewer queries on average than all its four\\ngreybox variants, demonstrating the superiority of our pretraining based deep RL approach. On the\\nonly publicly available task set IAM Vulnerable [1], TAC is able to detect 23 PEs (under a query\\nbudget of 10), and all 31 PEs (with a query budget of 20), which substantially outperforms all three\\nwhitebox baselines. Furthermore, TAC successfully detects two real-world PEs (with a query budget\\nof 60). The contributions of this paper are:\\n• Modeling. A comprehensive IAM modeling is introduced, providing the foundation of our\\nIAM greybox penetration testing approach.\\n• Approach. To our knowledge, TAC is the first interactive greybox penetration testing tool\\nto detect PEs due to IAM misconfigurations.\\n• Synthetic Data. An IAM PE synthesizer, IAMVulGen, is proposed.\\n2\\nBackground - IAM Basics\\nIAM Configurations. IAM configurations consist of entities and permissions. Entities represent\\nsubjects (e.g., users, user groups, services) or roles. Subjects actively perform actions, while roles\\nencapsulate job functions and responsibilities within an organization. Permissions define privileges\\nto perform operations and can be assigned directly or indirectly. Direct assignments apply to users,\\nuser groups, and roles, while indirect assignments depend on relationships between entities. For\\ninstance, a user inherits all permissions assigned to their user group, and a user assuming a role\\ngains all of the role’s permissions.\\nUser 1\\nUser 2\\nPerm 1\\nPerm 2\\nPerm 3\\nPermissions\\nService 1\\nRole 1\\nRole 2\\nGroup 1\\nEntities\\nFig. 1. IAM config. example.\\nFigure 1 illustrates an IAM configuration as a relational\\ngraph with six entities across four types: one user group\\n(Group 1), two users (User 1, User 2), one service (Service\\n1), and two roles (Role 1, Role 2); and three permissions:\\nPerm 1, Perm 2, and Perm 3. Entity-permission connections\\n(highlighted in orange) indicate direct assignments: Perm 1\\nand Perm 2 are assigned to Role 1, Perm 2 to Group 1, and\\nPerm 3 to Role 2. Entity-entity connections (highlighted\\nin blue) represent relationships between entities: user-group\\n(e.g., users in a group), user-role (e.g., a user assuming a role),\\nand service-role (e.g., a service assuming a role). Through\\nthese relationships, permissions can be inherited indirectly.\\nFor example, User 1 and User 2 in Group 1 indirectly obtain\\nPerm 2, while User 2 and Service 1 indirectly gain Perm 3 by assuming Role 2.\\nPEs due to Misconfigurations. PE in IAM [18, 26, 28] refers to exploiting IAM flaws to gain\\nunauthorized permissions for sensitive operations or access to sensitive data/resources. A primary\\ncause of PE is IAM misconfigurations, which this paper focuses on. Misconfigured IAM can enable\\nattackers to alter configurations, allowing them to obtain additional sensitive permissions. We define\\nthe untrusted entity as an attacker controlled entity and the target permission as the permission\\nthe attacker seeks to obtain illegally. PE occurs when the attacker controls the untrusted entity to\\nexploit IAM misconfigurations, assigning the target permission to the untrusted entity.\\n4\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nEntity 2\\n(User 1)\\nEntity 3\\n(User 2)\\nEntity 4\\n(Role 1)\\nEntity 5\\n(Role 2)\\nEntity 6\\n(Service 1)\\nPerm 2\\nPerm 1\\nPerm 2\\nPerm 3\\nEntity 1\\n(Group 1)\\n(a) Concrete PFG.\\nEntity 2\\n(User 1)\\nEntity 3\\n(User 2)\\nEntity 4\\n(Role 1)\\nEntity 5\\n(Role 2)\\nEntity 6\\n(Service 1)\\nPerm 2\\nPerm 1\\nPerm 2\\nPerm 3\\nEntity 1\\n(Group 1)\\nPerm 1\\nPerm 2\\nPerm 2\\nPerm 3\\nPerm 3\\n(b) Concrete modeling.\\nEntity 2\\n(User 1)\\nEntity 3\\n(User 2)\\nEntity 4\\n(Role 1)\\nEntity 5\\n(Role 2)\\nEntity 6\\n(Service 1)\\nPerm 2\\nPerm 1\\nPerm 2\\nPerm 3\\nEntity 1\\n(Group 1)\\nPerm 1\\nPerm 2\\nPerm 2\\nPerm 3\\nPerm 1\\nPerm 2\\nPerm 3\\n(c) Updated concrete PFG.\\nFig. 3. PFGs of the example in Figure 1; use green for enabled permission flows, red for disabled ones.\\nUser 1\\nUser 2\\nPerm 1\\nPerm 2\\nPerm 3\\nPermissions\\nService 1\\nRole 1\\nRole 2\\nGroup 1\\nEntities\\nFig. 2. Modified config. in PE\\nFigure 1 presents a crafted misconfiguration, a simplified\\nversion of a notorious 2019 IAM PE incident [27, 35], which\\ncompromised 100 million Capital One credit card applications\\nand accounts. In the incident, the attacker controls an EC2\\ninstance (Service 1, the untrusted entity) to assume Role 2,\\nwhich has access to the AWS Metadata Service. The attacker\\nexploits a Server-Side Request Forgery vulnerability of the\\nMetadata Service to obtain a temporary credential (Perm 3)\\nto assume Role 1. From Role 1, the attacker obtains the\\npermission (Perm 1, the target permission) to access an S3\\nbucket containing sensitive data . In our crafted example,\\nService 1 indirectly obtains Perm 3 by assuming Role 2\\nand uses it to assume Role 1, indirectly acquiring the target permission Perm 1.\\nThe example illustrates a single-step PE, where the untrusted entity uses one permission to realize\\nPE. However, a more complicated multi-step PE (or transitive PE) [21, 44] can occur, involving\\nmultiple permissions. This paper focuses on detecting both PE types.\\n3\\nIAM Modeling\\nWe present our concrete IAM modeling using our proposed Permission Flow Graph. We further\\npropose our abstract IAM modeling, which provides the foundation of our greybox penetration\\ntesting approach.\\n3.1\\nConcrete IAM Modeling\\nPermission Flow. We first propose the permission flow to model an indirect permission assignment\\nfrom one entity to another. Each permission flow has a flow state representing whether the flow\\nis currently enabled or disabled. If a flow from entity 𝑒1 to entity 𝑒2 is enabled, all permissions\\nassigned to 𝑒1 are automatically assigned to 𝑒2; if disabled, they are not.\\nA permission flow between two entities exists if a relation between the two entity types supports\\nindirect permission assignments. For instance, the user-role relation states that permissions assigned\\nto a role are indirectly assigned to any users assuming that role. In the example from Figure 1,\\nthere are four permission flows from Role 1 and Role 2 to User 1 and User 2. Note that the\\npermission flows can be manually extracted based on the semantics of entity-entity relations from\\nEfficient IAM Greybox Penetration Testing\\n5\\nAWS documentation and relevant studies[5, 18, 26, 28, 48]. Details about identifying permission\\nflows is introduced in Section 6.\\nThe flow state depends on the current relationship between entities. If currently related, the flow\\nis enabled; if not, it is disabled. In the illustrative example (Figure 1), User 1 is related to Role 1\\nbut not Role 2. Figure 3a shows its corresponding flow states: the flow from Role 1 to User 1 is\\nenabled, while the flow from Role 2 to User 1 is disabled.\\nPermission Space. We identify two types of permissions which the untrusted entity can exploit\\nto obtain the target permission: Type-I and Type-II permissions. A Type-I permission enables a\\npermission flow from entity 𝑒1 to entity 𝑒2, automatically assigning all permissions of 𝑒1 to 𝑒2. A\\nType-II permission directly assigns a Type-I or target permission (denoted as 𝑝) to an entity 𝑒.\\nFor example, adding a user to a user group is a Type-I permission, as it establishes a permission\\nflow; attaching an IAM policy to a user is a Type-II permission, as it directly assigns permissions\\nin the policy to the user.\\nThe permission space in our modeling includes all Type-I permissions (𝑃I), all Type-II permis-\\nsions (𝑃II), and the target permission (if neither Type-I nor Type-II). In the example (Figure 1),\\nPerm 1 represents the target permission, Perm 2 is a Type-II permission that allows its assigned\\nentity to directly assign Perm 1 to Role 1, and Perm 3 is a Type-I permission that allows its\\nassigned entity to assume Role 1, enabling a flow from the assigned entity to Role 1.\\nPermission Flow Graph. We propose the Permission Flow Graph (PFG) to concretely model an\\nIAM configuration, with entities as nodes and permission flows as edges. Formally, a PFG is defined\\nas 𝐺= (𝐸, 𝐹, A, W), where 𝐸represents the set of entities; 𝐹⊆𝐸× 𝐸represents permission flows;\\nA : 𝐸→2𝑃denotes a permission assignment function which maps entities to permissions in the\\npermission space 𝑃; and W : 𝐹→{true, false} indicates whether a flow is enabled (true) or\\ndisabled (false). Figure 3a illustrates a PFG which straightforwardly models the IAM configuration\\nin Figure 1. Three entities (Group 1, Role 1, and Role 2) have directly assigned permissions.\\nBased on the semantics of user-role, service-role, and user-group relations, each associated with\\nindirect permission assignments, 12 permission flows are identified. As shown in Figure 1, five of\\nthe entity-entity pairs are currently related, thus resulting in five enabled flows, while the remaining\\nseven are disabled.\\nConcrete Modeling of IAM Configurations. Given a PFG 𝐺= (𝐸, 𝐹, A, W), we define a\\npermission flow function M that generates a new PFG 𝐺′ = (𝐸, 𝐹, A′, W) after one permission\\nflow iteration. Formally, 𝐺′ = M(𝐺), where:\\nA′(𝑒2) =\\nØ\\n{(𝑒1,𝑒2)∈𝐹|W(𝑒1,𝑒2)=true}\\nA(𝑒1) ∪A(𝑒2),\\nmeaning that for each entity 𝑒2, all permissions of entities with enabled flows to 𝑒2 are assigned to\\n𝑒2.\\nTo model the IAM configuration, we apply the permission flow function iteratively on 𝐺until a\\nfixed point is reached. The resulting PFG, denoted 𝐺′, represents the concrete model of the IAM\\nconfiguration. Formally, 𝐺′ = M∗(𝐺), where M∗(𝐺) = M𝑛(𝐺) such that M𝑛(𝐺) = M𝑛−1(𝐺).\\nFigure 3b illustrates the concrete PFG derived from the IAM configuration in Figure 1, representing\\nthe fixed point of the PFG in Figure 3a. Based on five enabled permission flows, indirect assignments\\nupdate the PFG: 1) User 1 and User 2 indirectly obtain Perm 2 from Group 1; 2) User 2 and\\nService 1 indirectly obtain Perm 3 from Role 2; and 3) User 1 indirectly obtains Perm 1 and\\nPerm 2 from Role 1. The resulting PFG cannot be updated further, as it has reached a fixed point.\\nConcrete Modeling of IAM PEs. An IAM configuration has a PE iff the untrusted entity can\\nobtain the target permission through its assigned permissions. Formally, let 𝐺0 = (𝐸0, 𝐹0, A0, W0)\\n6\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nrepresent the initial IAM configuration, 𝑢the untrusted entity, and 𝑙∈𝑃\\\\ A0(𝑢) the target\\npermission. The configuration 𝐺0 has a PE iff there exists a sequence of permissions 𝑝1, . . . , 𝑝𝑛,\\nwhere 𝑝𝑖∈A𝑖−1(𝑢), and a modified configuration 𝐺𝑛= (𝐸𝑛, 𝐹𝑛, A𝑛, W𝑛) such that\\n𝐺0\\n𝑝1\\n↩→𝐺1 . . .\\n𝑝𝑛\\n↩→𝐺𝑛∧𝑙∈A𝑛(𝑢),\\nwhere 𝐺𝑖−1\\n𝑝𝑖\\n↩→𝐺𝑖indicates that the configuration 𝐺𝑖−1 is modified to 𝐺𝑖by the untrusted entity 𝑢\\nusing the permissions 𝑝𝑖∈A𝑖−1(𝑢).\\nFor example, consider the modeled concrete configuration in Figure 3b, where Service 1 is\\nthe untrusted entity and Perm 1 the target permission. When Service 1 applies Perm 3, the\\npermission flow from Role 1 to Service 1 is enabled, assigning all permissions of Role 1 (i.e.,\\nPerm 1 and Perm 2) to Service 1. This modification is denoted as 𝐺0\\nPerm 3\\n↩→\\n𝐺1, where 𝐺0 is\\nthe original configuration, and 𝐺1, shown in Figure 3c, is the resulting configuration. Since Perm\\n1 is now assigned to Service 1 (Perm 1 ∈A1(Service 1)), the original configuration 𝐺0 is\\ndetermined to have a PE.\\n3.2\\nAbstract IAM Modeling\\nThe concrete IAM modeling above requires full access to the IAM configuration, but not all\\npermission assignments are necessary for detecting PEs. For example, the PE in Figure 2 can\\nbe detected using only partial information: Service 1 owns Perm 3, and Role 1 owns Perm\\n1. Building on this insight, we propose abstract IAM modeling that identifies PEs using partial\\npermission assignments, forming the basis of our greybox penetration testing technique.\\nEntity 2\\n(User 1)\\nEntity 3\\n(User 2)\\nEntity 4\\n(Role 1)\\nEntity 5\\n(Role 2)\\nEntity 6\\n(Service 1)\\nPerm 2\\nPerm 1\\nPerm 2\\nPerm 3\\nEntity 1\\n(Group 1)\\nPerm 1\\nPerm 2\\nPerm 2\\nPerm 3\\nPerm 3\\nFig. 4. The visible PFG.\\nAbstract PFG. The abstract PFG models IAM configurations with\\npartially visible entities and visible permission flows among them,\\nwhere flow states are unknown. In the illustrative example, the\\nvisible entities are User 1, Role 1, and Service 1, and the visible\\npermission flows are shown in Figure 4.\\nUsing the visible entity space 𝐸vis ⊆𝐸and the visible permission\\nflow space 𝐹vis ⊆𝐹, we construct a visible permission space 𝑃vis ⊆\\n𝑃. This space includes Type-I and Type-II permissions related to\\n𝐸vis or 𝐹vis (i.e., permissions that directly assign permissions to\\na visible entity or enable a visible permission flow) and the target\\npermission. The abstract PFG is defined as a tuple ˆ𝐺= ( ˆ𝐸, ˆ𝐹, ˆ\\nA, ˆ\\nW),\\nwhere ˆ𝐸denotes the abstract entity space, ˆ𝐹denotes the abstract\\npermission flow space, ˆ\\nA denotes the abstract entity-permission\\nstate function, and\\nˆ\\nW denotes the abstract permission flow state\\nfunction. Each component is detailed below.\\nTo construct our abstract entity space and permission flow space, we begin by transforming each\\nType-II permission into a Type-I permission. This transformation simplifies state transitions,\\nas explained later in this section. Recall that a Type-II permission 𝑠, when assigned to an entity,\\nallows it to directly assign a target permission or a Type-I permission 𝑡𝑠to an entity 𝑒𝑠. For each\\nType-II permission 𝑠, we 1) add a pseudo entity 𝛽𝑠assigned the corresponding target or Type-I\\npermission 𝑡𝑠, and 2) add a pseudo permission flow from 𝛽𝑠to the entity 𝑒𝑠. This way, each Type-II\\npermission 𝑠becomes a Type-I permission which allows the assigned entity to enable the pseudo\\npermission flow from 𝛽𝑠to 𝑒𝑠. Using these transformations, we define the abstract entity space ˆ𝐸\\nand abstract flow space ˆ𝐹by extending the visible entity space 𝐸vis and visible flow space 𝐹vis with\\nEfficient IAM Greybox Penetration Testing\\n7\\npseudo entities and pseudo flows, respectively. Formally, ˆ𝐸= 𝐸vis ∪{𝛽𝑠|𝑠∈𝑃II ∩𝑃vis ∧𝑒𝑠∈𝐸vis},\\nand ˆ𝐹= 𝐹vis ∪{(𝛽𝑠,𝑒𝑠)|𝑠∈𝑃II ∩𝑃vis ∧𝑒𝑠∈𝐸vis}.\\nNext, we define the abstract entity-permission state function\\nˆ\\nA : ˆ𝐸× 𝑃vis →{?, +}, which\\nassigns an abstract state to each entity-permission pair. Specifically, ˆ\\nA(𝑒, 𝑝) =? means that it is\\nunknown whether permission 𝑝can be assigned to entity 𝑒. ˆ\\nA(𝑒, 𝑝) = + means that permission 𝑝\\ncan be assigned to entity 𝑒, either directly or indirectly. Initially, ˆ\\nA assigns ? to all pairs, except for\\npseudo entities and their corresponding Type-I or target permissions (involved in the Type-II\\npermission). Formally, the initial state is defined as:\\nˆ\\nAinit(𝑒, 𝑝) =\\n(\\n+,\\n∃𝑠∈𝑃II ∩𝑃vis. 𝑒= 𝛽𝑠∧𝑝= 𝑡𝑠,\\n?,\\notherwise.\\nThe abstract permission flow state function\\nˆ\\nW : ˆ𝐹→{∗, ⊕} assigns abstract states to permission\\nflows.\\nˆ\\nW(𝑓) = ∗means that it is unknown whether the permission flow 𝑓can be enabled.\\nˆ\\nW(𝑓) = ⊕means that the permission flow 𝑓can be enabled. Initially, all permission flows are\\nmapped to ∗, formally defined as ∀𝑓∈ˆ𝐹,\\nˆ\\nWinit(𝑓) = ∗.\\nFigure 6a shows an initial abstract PFG ˆ𝐺init = ( ˆ𝐸, ˆ𝐹, ˆ\\nAinit, ˆ\\nWinit), representing the abstract\\nmodeling of the visible concrete PFG shown in Figure 4. Recall that Perm 2 is a Type-II permission\\nallowing its assigned entity to directly assign the target permission Perm 1 to Role 1. This is\\ntransformed into a Type-I permission by adding a pseudo entity Entity 𝛽perm 2 and a pseudo\\nflow from Entity 𝛽perm 2 to Role 1. The abstract entity space is expanded with Entity 𝛽perm 2,\\nand the abstract permission flow space includes the new pseudo flows. Entity-permission states\\nare initialized to ?, except for the pseudo entity Entity 𝛽perm 2 and the target permission Perm 1\\n(involved in the Type-II permission Perm 2), which are set to +. All flow states are initialized to ∗.\\nAbstract Permission Flow Function. Given an abstract PFG ˆ𝐺= ( ˆ𝐸, ˆ𝐹, ˆ\\nA, ˆ\\nW), the abstract\\npermission flow function ˆ\\nM performs one permission flow iteration, producing a new PFG ˆ𝐺′ =\\n( ˆ𝐸, ˆ𝐹, ˆ\\nA′, ˆ\\nW′). Formally, ˆ𝐺′ =\\nˆ\\nM( ˆ𝐺), where:\\nˆ\\nA′(𝑒, 𝑝) =\\n(\\n+,\\nC1: ∃𝑒′ ∈𝑁(𝑒)\\n⊕. ˆ\\nA(𝑒′, 𝑝) = +,\\nˆ\\nA(𝑒),\\n𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒.\\nˆ\\nW′(𝑓) =\\n\\x1a\\n⊕,\\nC2: ∃𝑝∈𝑃I ∩𝑃vis.J𝑝K = 𝑓∧ˆ\\nA(𝑢, 𝑝) = +,\\nˆ\\nW(𝑓),\\n𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒.\\nHere, 𝑁(𝑒)\\n⊕\\n= {𝑒′|(𝑒′,𝑒) ∈ˆ𝐹∧\\nˆ\\nW(𝑒′,𝑒) = ⊕}; J𝑝K refers to the permission flow that can be enabled\\nwith the Type-I permission 𝑝.\\nEntity e’\\n…\\np\\n…\\n…\\n+\\n…\\n…\\np\\n…\\n…\\n?\\n…\\nEntity e\\n…\\np\\n…\\n…\\n+\\n…\\n…\\np\\n…\\n…\\n?\\n…\\nEntity e’\\n…\\np\\n…\\n…\\n+\\n…\\n…\\np\\n…\\n…\\n?\\n…\\nEntity e\\n…\\np\\n…\\n…\\n+\\n…\\n…\\np\\n…\\n…\\n+\\n…\\n(a) C1 update.\\nEntity e’\\nEntity u\\n…\\np\\n…\\n…\\n+\\n…\\n…\\np\\n…\\n…\\n+\\n…\\n…\\n…\\n*\\nEntity e\\n…\\n…\\nEntity e’\\nEntity u\\n…\\np\\n…\\n…\\n+\\n…\\n…\\n…\\nEntity e\\n…\\n…\\n(b) C2 update.\\nFig. 5. Abstract state updates\\nCondition C1 updates the abstract state of an entity-\\npermission pair (shown in Figure 5a). If there exists\\nan entity 𝑒′ having the permission 𝑝(abstract state +)\\nand an enabled permission flow (abstract flow state ⊕)\\nfrom the entity 𝑒′ to an entity 𝑒, then 𝑒can have the\\npermission 𝑝, updating the state of (𝑒, 𝑝) to +.\\nCondition C2 updates the abstract state of a permis-\\nsion flow (shown in Figure 5b). If an untrusted entity 𝑢\\nhas a permission 𝑝(abstract state of (𝑢, 𝑝) is +), which\\nis a Type-I permission that allows to enable a flow 𝑓,\\nthen the abstract state of 𝑓is updated to ⊕.\\n8\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nAbstract IAM Configuration Modeling. Similar to\\nconcrete IAM configuration modeling, we perform a\\nfixed-point iteration on an abstract PFG ˆ𝐺using the abstract permission flow function\\nˆ\\nM. The\\nresulting PFG ˆ𝐺′ serves as our abstract model of the IAM configuration. Formally, ˆ𝐺′ =\\nˆ\\nM∗( ˆ𝐺),\\nwhere ˆ\\nM∗represents the fixed-point iteration of ˆ\\nM (i.e., ˆ\\nM∗(𝐺) =\\nˆ\\nM𝑛(𝐺) such that ˆ\\nM𝑛(𝐺) =\\nˆ\\nM𝑛−1(𝐺)).\\nIn particular, the initial abstract PFG ˆ𝐺init = ( ˆ𝐸, ˆ𝐹, ˆ\\nAinit, ˆ\\nWinit), represents the initial abstract IAM\\nconfiguration. The terminal abstract IAM configuration is denoted as ˆ𝐺term = ( ˆ𝐸, ˆ𝐹, ˆ\\nAterm, ˆ\\nWterm),\\nwhere ˆ\\nAterm(𝑢,𝑙) = +. All other configurations are considered intermediate abstract IAM configu-\\nrations. Figure 6 illustrates these three types of configurations derived from the partially visible\\nPFG in Figure 4.\\n4\\nGreybox Penetration Testing for Detecting IAM PEs\\nBased on abstract IAM modeling, we propose a greybox penetration testing approach for detecting\\nIAM PEs, without requiring a complete IAM configuration. Unlike existing whitebox penetration\\ntesting approaches which force their customers to pay lots of manual efforts to blindly eliminate\\nall sensitive information of their IAM configurations, our greybox approach actively interacts with\\ncloud customers to query only the essential information related to PE detection.\\nOur approach only requires cloud customers to provide two simple initial inputs beforehand: 1)\\nthe type of the untrusted entity and the target permission; and 2) visible entities that customers are\\ninclined to be queried with. We automatically anonymize each visible entity (including the untrusted\\nentity) with randomly generated IDs, construct visible permissions linked to these renamed entities,\\nand define visible permission flows (with unknown states) based on entity types. These elements\\nform the initial abstract IAM configuration. For the illustrative example, suppose the customer\\nchooses User 1, Role 1 and Service 1 as visible entities, they are renamed as Entity 2, Entity\\n4, and Entity 6, respectively. The initial abstract IAM configuration is shown in Figure 6a.\\nOur interactive greybox approach delivers one query to the cloud customer at a time, inquiring\\nwhether a visible permission is assigned to a visible entity. The cloud customer can choose to either\\nrespond to or decline the query, based on their knowledge of whether the inquired permission\\nassignment information is confidential. Formally, let 𝑄= 𝐸vis × 𝑃vis be the query space. The\\ncustomer’s response for a concrete IAM configuration 𝐺= (𝐸, 𝐹, A, W) is defined as a function\\nO : 𝑄↦→{true, false, unknown} satisfying\\nO(𝑒, 𝑝) =\\n\\uf8f1\\uf8f4\\uf8f4\\uf8f4\\uf8f2\\n\\uf8f4\\uf8f4\\uf8f4\\uf8f3\\ntrue,\\n𝑎𝑐𝑐𝑒𝑝𝑡∧𝑝∈A(𝑒),\\nfalse,\\n𝑎𝑐𝑐𝑒𝑝𝑡∧𝑝∉A(𝑒),\\nunknown,\\n¬𝑎𝑐𝑐𝑒𝑝𝑡\\nwhere 𝑎𝑐𝑐𝑒𝑝𝑡denotes whether the customer accepts to answer the query.\\nOur approach enables cloud customers to specify the number of queries they are willing to\\naccept, namely the query budget. Within this budget, the approach determines whether a PE is\\ndetected. An IAM configuration is considered to have a PE iff its initial abstract configuration can\\nbe updated to a terminal abstract configuration, based on customer query responses. Formally, let\\nˆ𝐺0 = ( ˆ𝐸0, ˆ𝐹0, ˆ\\nA0, ˆ\\nW0) be the initial abstract IAM configuration, 𝑢the untrusted entity, and 𝑙the\\ntarget permission. The initial abstract IAM configuration ˆ𝐺0 has a PE iff there exists a sequence of\\nqueries (𝑒1, 𝑝1), . . . , (𝑒𝑛, 𝑝𝑛) ∈𝑄, and a terminal abstract IAM configuration ˆ𝐺𝑛= ( ˆ𝐸𝑛, ˆ𝐹𝑛, ˆ\\nA𝑛, ˆ\\nW𝑛)\\nsuch that\\nˆ𝐺0\\n(𝑒1,𝑝1)\\n↩→\\nˆ𝐺1 . . .\\n(𝑒𝑛,𝑝𝑛)\\n↩→\\nˆ𝐺𝑛∧ˆ\\nA𝑛(𝑢,𝑙) = +,\\nEfficient IAM Greybox Penetration Testing\\n9\\nwhere ˆ𝐺𝑖−1\\n(𝑒𝑖,𝑝𝑖)\\n↩→\\nˆ𝐺𝑖annotates that the abstract IAM configuration ˆ𝐺𝑖−1 is updated to ˆ𝐺𝑖based on\\nthe customer response to the query (𝑒𝑖, 𝑝𝑖):\\nˆ𝐺𝑖=\\n( ˆ\\nM∗( ˆ𝐺𝑖−1[ ˆ\\nA𝑖−1[𝑒𝑖, 𝑝𝑖] ↦→+]),\\nO(𝑒𝑖, 𝑝𝑖) = true,\\nˆ𝐺𝑖−1,\\n𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒.\\nOur abstract IAM modeling and state updating rules ensure the precision of IAM PE detection, mean-\\ning\\nthat\\nany\\nPEs\\nwhich\\nare\\nidentified\\nby\\nTAC\\nare\\nguaranteed\\nto\\nbe\\nvalid.\\n*\\n*\\n*\\nEntity βperm2\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n+\\nEntity 4 (Role 1)\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n?\\nEntity 2 (User 1)\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n?\\nEntity 6 (Service 1)\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n?\\n*\\n(a) Initial abstract config. representing the visible\\nPFG in Figure 4.\\n*\\n*\\n*\\nEntity βperm2\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n+\\nEntity 4 (Role 1)\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n?\\nEntity 2 (User 1)\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n?\\nEntity 6 (Service 1)\\nPerm3\\nPerm2\\nPerm1\\n+\\n?\\n?\\n(b) Intermediate abstract config. with response\\nO(Entity 6, Perm 3).\\n*\\n*\\nEntity βperm2\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n+\\nEntity 4 (Role 1)\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n+\\nEntity 2 (User 1)\\nPerm3\\nPerm2\\nPerm1\\n?\\n?\\n?\\nEntity 6 (Service 1)\\nPerm3\\nPerm2\\nPerm1\\n+\\n?\\n+\\n*\\n(c) Terminal abstract config. with response\\nO(Entity 4, Perm 1).\\nFig. 6. An example for IAM interactive greybox\\npenetration testing.\\nWe use the illustrative example in Figure 6\\nto demonstrate how TAC interacts with a cus-\\ntomer through queries to detect IAM PEs. Start-\\ning with the initial abstract IAM configuration\\nin Figure 6a, our approach may query whether\\nEntity 6 initially has Perm 3 (query: (Entity\\n6, Perm\\n3)). The customer responds true (i.e.,\\nO(Entity 6, Perm 3) = true), updating the ab-\\nstract state of (Entity 6, Perm 3) to +. Since Perm\\n3 is the Type-I permission which allows its as-\\nsigned entity (i.e., Entity 6) to enable the flow\\nfrom Entity 4 to Entity 6. Thus, the abstract\\nstate of this flow is updated to ⊕, resulting in the\\nintermediate abstract IAM configuration shown in\\nFigure 6b. Next, our approach may query whether\\nEntity 4 has the target permission Perm 1 (query:\\n(Entity 4, Perm 1)). The customer again responds\\ntrue (i.e., O(Entity 4, Perm 1) = true), updating\\nthe state of (Entity 4, Perm 1) to +. According to\\ncondition C1 of the abstract permission flow func-\\ntion\\nˆ\\nM, the state of (Entity 6, Perm 1) is also\\nupdated to +. Since the initial IAM configuration\\ncan be updated to the terminal abstract IAM config-\\nuration in Figure 6c, the configuration is confirmed\\nto have a PE.\\n5\\nEfficient IAM Greybox Penetration Testing\\nTo make our greybox testing approach is practical,\\nwe focus on improving efficiency by minimizing the\\ncustomer’s manual inputs, specifically reducing the\\nnumber of query responses. This requires detecting\\nIAM PEs with as few queries as possible within the\\nspecified query budget. The problem is a sequential decision-making problem, where each query is\\nselected based on the customer’s responses to previous queries. For instance, in the example in\\nFigure 6, if the response to the first query confirms that Entity 6 has Perm 3, it makes sense to\\nfollow up with a second query about whether Entity 4 has Perm 1. This is because Perm 3 could\\nenable a permission flow from Entity 4 to Entity 6, potentially assigning Perm 1 to Entity 6,\\nthereby revealing a PE. However, if the response shows that Entity 6 does not have Perm 3, the\\n10\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nReward\\nFeedback\\nQuery\\xa0\\nModel\\nAbstract\\xa0\\nIAM\\xa0Config.\\nQuery\\nReward\\nState\\nAction\\nEnvironment\\nRL\\xa0Agent\\nPrivilege\\xa0\\nEscalation\\nLearning\\xa0\\nAlgorithm\\nCustomer\\nQuery\\nBudget\\nVisibility\\nAbstract\\xa0IAM\\xa0\\nModeling\\nInitial\\xa0Inputs\\nResponse\\nFig. 7. The general framework of TAC.\\nsecond query would be inefficient for revealing any PEs. In that case, a different query should be\\nselected for PE detection.\\nTo address the sequential decision-making problem, we propose an efficient greybox approach\\ncalled TAC, which leverages RL to minimize the number of queries required to detect IAM PEs.\\n5.1\\nOverview\\nThe framework of TAC is based on our RL formulation of the problem, as illustrated in Figure 7.\\nIn each episode, the RL agent starts with its visibility, an initial abstract IAM configuration, and\\na query budget. The agent iteratively sends queries to update the abstract IAM configuration\\nuntil either a PE is identified or the query budget is reached. At each step, the agent uses a query\\nmodel (i.e., the RL policy) to select a query (i.e., the action) based on the current abstract IAM\\nconfiguration (i.e., the state). In the RL environment, the abstract IAM configuration is updated\\nbased on the customer’s query response, and a reward of −1 per query is provided by a reward\\nfeedback module. The RL agent uses the classic Actor-Critic Method [47] to update the query\\nmodel based on the feedback. The objective of the RL agent is to learn an optimal query model that\\nmaximizes the return (i.e., cumulative rewards), effectively minimizing the number of queries needed.\\nPseudo\\n(βperm2 )\\nOther\\n(entity 4)\\nUntrusted\\n(entity 6)\\nTarget\\n(perm 1)\\nType-I\\n(perm 2)\\n…\\n…\\n+\\n?\\n?\\n?\\n?\\n?\\nFig. 8. Graph representation of the abstract config. in\\nFigure 6b. Entity nodes are circles, permission nodes\\nare triangles, entity-entity edges (flows) are blue, and\\nentity-permission edges are orange. Solid lines indicate\\npermission assignments; dotted and dashed lines rep-\\nresent edges from the source or sink of a Type-I flow\\nto the Type-I permission.\\nOur RL formulation requires the agent to\\ndetect a PE within a single episode. However,\\nclassic deep RL approaches [47], which train\\npolicies from scratch with randomly initialized\\nweights, typically require numerous episodes to\\nmaximize returns. Inspired by recent advances\\nin zero-shot and few-shot learning for language\\nmodels [13, 37], we pretrain our query model\\non a diverse set of PE tasks using multi-task RL\\nacross multiple episodes. This pretraining aims\\nto improve the model’s query efficiency on new\\nPE tasks within a single episode.\\nHowever, existing multi-task RL techniques [14,\\n17, 46] usually suffer from the negative transfer\\nissue, where training on some tasks adversely\\naffects performance on others [40, 45]. To ad-\\ndress this, we use domain knowledge in IAM\\nEfficient IAM Greybox Penetration Testing\\n11\\nPE detection to partition the PE task space into subspaces, grouping tasks that are less likely to\\ninterfere with one another. A specialized query model is then pretrained for each subspace. Further\\ndetails on the query model design and our approach to mitigating negative transfer are discussed\\nas follows.\\n5.2\\nQuery Model\\nOur query model generates embeddings for each query based on the current state of the abstract\\nIAM configuration. These embeddings are used to infer a probability distribution over the query\\nspace, guiding the selection of the next query. Leveraging the inherently graph-structured nature\\nof IAM configurations (Figure 6), we encode them into graph representations and apply GNNs to\\ngenerate the query embeddings.\\nGNNs are particularly well-suited for this task due to their ability to process and generalize\\nacross diverse graph structures, enabling pretraining across a wide range of PE tasks from different\\nsubspaces. Additionally, GNNs are efficient at handling large-scale graphs, processing millions of\\nnodes and edges using moderate GPU resources. This scalability allows the query model to manage\\nreal-world IAM configurations with millions of entities, permissions, and permission flows. Further\\ndetails on the graph representations, model architecture, and pretraining process are provided in\\nthe following subsection.\\nThe Graph Representation. In this subsection, we describe how an abstract IAM configuration is\\ntransformed into a directed graph representation, which serves as input for our GNN-based query\\nmodel. The graph nodes are classified into two main types: entity nodes and permission nodes.\\nEntity nodes are further divided into three subtypes: pseudo entities, untrusted entities, and other\\nentities. Permission nodes are categorized as target permissions or Type-I permissions (all Type-II\\npermissions are converted into Type-I permissions, as explained in Section 3.2). The directed edges\\nin the graph are generally classified into two types, entity-entity type representing permission\\nflows, and entity-permission type including three sub-types: (1) edges representing permission\\nassignments from an entity to one of its assigned permissions; (2) edges from a source entity of a\\nType-I permission flow to the corresponding Type-I permission; and (3) edges from the sink entity\\nof a Type-I permission flow to the corresponding Type-I permission. Each permission assignment\\nedge in subtype (1) with an unknown abstract state (?) represents a potential query. Node and\\nedge features include their corresponding types. Additionally, edges representing permission flows\\nand assignments carry their abstract values,\\nˆ\\nW and ˆ\\nA, respectively. Figure 8 illustrates the graph\\nrepresentation of the abstract IAM configuration shown in Figure 6b.\\nGNN-based Model Design. Given the graph representation of the abstract IAM configuration,\\nthe GNN-based query model selects an entity-permission edge with an abstract state ? (unknown)\\nbased on the inferred probability distribution. It then outputs the corresponding query for the\\nselected edge. The goal of the model is to predict permission assignments with unknown states\\nthat are most critical for PE detection.\\nFigure 9 illustrates the design and workflow of our GNN-based query model. Starting with a graph\\nrepresentation of an abstract IAM configuration (A), five stacked Graph Attention Network (GATv2)\\nlayers [12] generate embeddings for permission assignment edges (B). A Multi-Layer Perceptron\\n(MLP) then predicts a probability distribution over query edges (permission assignment edges\\nwith an abstract state ?), as shown in (C). Finally, a query edge is selected based on the predicted\\ndistribution and converted into a query corresponding to the selected entity and permission. For\\nexample, in Figure 9, the edge from Entity 4 to Perm 1 is selected due to its highest probability,\\nresulting in the query (Entity 4, Perm 1) as the output of the model.\\n12\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nQuery\\n(Entity 4, Perm 1)\\nGNN Layers\\nβperm2 \\nEntity 4\\nEntity 6\\nPerm 1 \\nPerm 2\\n+\\n?\\n?\\n?\\n?\\n?\\nβperm2 \\nEntity 4\\nEntity 6\\nPerm 2\\nPerm 1\\nβperm2 \\n0.1\\n0.7\\n0.05\\n0.01\\n0.1\\nEntity 4\\nEntity 6\\nPerm 2\\nPerm 1\\n(A)\\n(B)\\n(C)\\nMLP Layer\\nGNN Layers\\nGNN Layers\\nFig. 9. The design and workflow of the query model.\\nModel Pretraining. To address the negative transfer issue mentioned in Section 5.1, our intuition\\nis that PE tasks involving the same untrusted entity type are likely to share similar optimal query\\npolicies for detecting PEs. Therefore, they are unlikely to interfere with each other during model\\npretraining. Based on this intuition, we pretrain a query model on PE tasks with the same untrusted\\nentity type. Specifically, given a set of pretraining tasks, we first divide them into groups according\\nto their untrusted entity types. For each group, we pretrain a distinct query model specialized\\nfor handling PE tasks with that specific untrusted entity type. This is achieved using RL with\\na sequential task scheduling strategy, where PE tasks in the group are randomly shuffled and\\nsequentially used to optimize the query model over multiple episodes per task.\\n6\\nIAMVulGen - IAM PE Synthesizer\\nOur pretraining and evaluation processes require a large, diverse, and challenging set of IAM PE\\ntasks. However, the only publicly available dataset, IAM Vulnerable [1], contains just 31 relatively\\nsimple tasks. To overcome this limitation, we developed IAMVulGen, a tool designed to generate\\ndiverse and realistic IAM PE tasks reflective of real-world scenarios.\\nTo achieve this, we manually identified 72 common entity types and extracted 219 permission\\nflow templates from official AWS documentation [4–6] and studies on IAM PEs [18, 26, 28, 48].\\nThese templates define possible permission flows between different entity types. For example, one\\ntemplate specifies that permissions flow from a user group to its members, as AWS documentation\\nstates that permissions assigned to a group are automatically inherited by its users. By leveraging\\nthese templates, IAMVulGen ensures the generated data reflects real-world IAM configurations.\\nThe identified entity types and templates create thousands of potential entities and millions of\\npossible permissions, enabling IAMVulGen to synthesize IAM misconfigurations of any desired size\\nwithin this space. IAMVulGen generates each IAM PE task in two steps: (1) creating a concrete IAM\\nmisconfiguration and (2) constructing the corresponding initial abstract IAM misconfiguration.\\nThe details of these steps are described below.\\nStep 1: Concrete Misconfiguration Generation. To generate a concrete IAM misconfiguration\\nwith PE, IAMVulGen constructs a PFG 𝐺= (𝐸, 𝐹, A, W) by generating its components step by step.\\n1) Entity space 𝐸Based on 72 manually identified common entity types, including user, user group,\\nrole, and 69 service types, IAMVulGen uniformly samples 𝑛entity types (𝑛∈[1, 5] by default) from\\nthese categories. For each selected type, it generates 𝑚entities (𝑚∈[1, 20] by default).\\n2) Permission flow space 𝐹: Using 219 manually extracted permission flow templates, which\\ndefine entity pairs that can have permission flows, IAMVulGen generates permission flows for all\\nentity pairs in 𝐸that matches the templates.\\n3) Permission assignment A: IAMVulGen first generates the permission space 𝑃, which includes\\nType-I, Type-II, and target permissions. A Type-I permission is created for each permission\\nflow to enable it. For Type-II permissions, three entity types (i.e., user, user group and role) are\\nidentified which can be directly assigned with a Type-I/target permission; for each entity with one\\nEfficient IAM Greybox Penetration Testing\\n13\\nof these types and each Type-I/target permission, IAMVulGen generates a Type-II permission for\\nassigning the Type-I/target permission to the entity. Target permissions, such as those granting\\naccess to sensitive S3 buckets, are manually identified from AWS IAM security best practices [6] and\\nstudies [18, 26, 28, 48]. Using the generated permission space 𝑃, IAMVulGen assigns 𝛾𝑝(𝛾𝑝= 20%\\nby default) of the permissions to each entity, uniformly sampled from 𝑃.\\n4) Flow state function W: the state of each permission flow is set to true with a probability of\\n𝛾𝑤(𝛾𝑤= 0.2 by default).\\nFinally, the fixed-point iteration is applied to the generated PFG, producing the final concrete IAM\\nconfiguration.\\nUsing the generated IAM configuration, IAMVulGen uniformly selects an entity and a permission\\nfrom the generated entity and permission spaces to serve as the untrusted entity and the target\\npermission, respectively. It then applies three state-of-the-art whitebox PE detectors to check for a\\nPE in the configuration. If at least one detector identifies a PE, the concrete misconfiguration is\\nfinalized; otherwise, the process repeats with a new configuration.\\nStep 2: Initial Abstract Misconfiguration Generation. Based on the created concrete misconfig-\\nuration, IAMVulGen creates the corresponding initial abstract IAM misconfiguration by uniformly\\nsampling 𝛾𝑣(𝛾𝑣= 20% by default) of the entities from the concrete misconfiguration as visible\\nentities.\\n7\\nEvaluation\\n7.1\\nExperimental Setup\\nPE Task Sets. For pretraining, we generate a task set, Pretrain, containing 2,000 IAM PE tasks\\ncreated by IAMVulGen under its default settings. For evaluation, we use three distinct test sets: (1)\\nTest-A, with 500 tasks generated by IAMVulGen; (2) Test-B, with 31 tasks from the public IAM PE\\nbenchmark IAM Vulnerable [1]; (3) Test-C, with two large real-world misconfigurations collected\\nfrom a cloud security startup. None of the testing and pretraining sets have overlap with each other.\\nAppendix A shows details about these sets.\\nCustomer Query Response Simulation. TAC interacts with cloud customers to detect IAM PEs.\\nTo evaluate its performance across hundreds of PE tasks, we develop a customer query response\\nsimulator. For each IAM PE task, the simulator randomly samples queries from the query space to\\nrepresent those customers are accept to answer. Given an IAM configuration and a query selected\\nby TAC, the simulator determines whether to accept the query based on the sampled query set and\\nprovides an answer using the concrete configuration.\\nBaselines. Given the lack of publicly available greybox or blackbox IAM PE detectors, we use\\nthree state-of-the-art open-source whitebox PE detectors as baselines: Pacu [30], Cloudsplaining\\n[42], and PMapper [19]. To evaluate TAC’s IAM concrete modeling, we include its whitebox variant,\\nTAC-WB, which applies only concrete IAM modeling for PE detection. To assess the impact of our\\nGNN-based RL approach, we introduce two greybox variants: TAC-RD, which randomly selects\\nqueries, and TAC-EA, which uses a query model trained with the evolutionary algorithm CMA-\\nES [20]. We also analyze the effect of pretraining on query model performance with TAC-NoPT,\\nwhere the model is not pretrained. Lastly, to study how our pretraining mitigates negative transfer,\\nwe include TAC-MamlPT, which uses the multi-task RL technique MAML [16] for pretraining.\\nEvaluation Metrics. To evaluate TAC’s effectiveness, we use the false negative rate (FNR) of the\\nIAM PE detection as the metric. False positive rates are not measured since all detectors in our\\nexperiments are precise, ensuring all detected PEs are true. For efficiency evaluation, we use the\\nquery count, representing the number of queries used to interact with customers during detection.\\n14\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nQuery Budgets. In real-world scenarios, customers determine the query budget based on their\\nwillingness to answer queries. A larger budget provides TAC with more information, improving\\nits ability to detect PEs. To challenge TAC and evaluate its performance, we use smaller query\\nbudgets here. For Test-A and Test-C task sets, we set 10 query budgets: 10, 20, ..., 100, which\\nare significantly smaller than the maximum query space size of 8, 448. For Test-B task set, with a\\nmaximum query space size of 27, we use two query budgets: 10 and 20.\\nHyper-Parameter Settings. During pretraining, each task is used for 20 episodes to train the query\\nmodel. The AdamW optimizer [32] with a learning rate of 10−4 is applied for both pretraining and\\ntesting. To ensure reliable results, all experiments, including pretraining and testing, are repeated\\n11 times.\\n7.2\\nResearch Questions\\nWe evaluate effectiveness of our IAM modeling and TAC through the following research questions:\\nRQ1: How effective is our concrete IAM modeling?\\nRQ2: How effective is TAC in terms of FNR?\\nRQ3: How effective is TAC in terms of query count?\\nNote that the overall effectiveness of TAC, as examined in RQ2 and RQ3, reflects the impact of our\\nabstract IAM modeling.\\n7.3\\nExperimental Results\\nRQ1: Effectiveness of Concrete IAM Modeling. To evaluate our concrete IAM modeling, we\\ntested all three whitebox baselines and TAC-WB on the Test-A, Test-B, and Test-C task sets.\\nTAC-WB detected all PEs across the three sets, achieving a zero FNR. In contrast, on Test-A, the\\nFNRs for PMapper, Pacu, and Cloudsplaining were 12%, 20%, and 26%, respectively. On Test-B,\\ntheir rates increased to 29%, 32%, and 39%. For Test-C, all three failed to detect either PE, resulting\\nin a 100% FNR. Our manual inspection revealed that FNRs in pattern-based detectors (Pacu and\\nCloudsplaining) were due to missing relevant PE patterns, while those in the graph-based detector\\n(PMapper) stemmed from limited graph representation expressiveness. Overall, the zero FNR of\\nTAC-WB highlights the significant advantages of our concrete modeling.\\nRQ2: Effectiveness of TAC in FNR. Figure 10a illustrates the FNRs of TAC on the Test-A set,\\ncompared to four whitebox baselines and its four greybox variants across 10 query budgets. As\\nthe query budget increases from 10 to 100, TAC’s FNR drops significantly from 57% to 27%, consis-\\ntently outperforming its greybox variants. Additionally, the near-zero standard deviation of TAC’s\\nFNR highlights its superior stability over the greybox variants. These findings demonstrate the\\neffectiveness of both the GNN-based RL approach and pretraining in improving TAC. Compared\\nto whitebox baselines, TAC achieves a FNR of 27% under a query budget of 100, closely matching\\nCloudsplaining (26%) and only 6% and 14% higher than Pacu and PMapper, respectively. This\\nresult underscores TAC’s strong performance as a greybox detector with limited information. En-\\ncouraged by these results, we further increased TAC’s query budget, finding that it outperforms\\nall three whitebox baselines when the budget reaches 258. This demonstrates the superiority of\\nour IAM modeling approach, which accounts for a broader class of PEs than the state-of-the-art\\nwhitebox baselines. Overall, the results confirm that TAC achieves competitive effectiveness on the\\nTest-A set, outperforming its greybox variants and rivaling whitebox baselines.\\nOn the Test-B set, TAC detects 23 PEs with a query budget of 10 (3% FNR) and all 31 PEs with\\na budget of 20 (0% FNR), outperforming three whitebox baselines (29%-39% FNRs) and matching\\nTAC-WB. In contrast, TAC’s greybox variants detect 17–22 PEs with a budget of 10 (29%-45% FNRs)\\nand 23–30 PEs with a budget of 20 (3%-26% FNRs). On the Test-C set, TAC detects both PEs with\\nEfficient IAM Greybox Penetration Testing\\n15\\n10\\n20\\n30\\n40\\n50\\n60\\n70\\n80\\n90\\n100\\nQuery Budget\\n0.0\\n0.2\\n0.4\\n0.6\\n0.8\\n1.0\\nFalse Negative Rate\\nCloudsplaining\\nPacu\\nPMapper\\nTAC-WB\\nTAC\\nTAC-MamlPT\\nTAC-NoPT\\nTAC-EA\\nTAC-RD\\nWhitebox\\n(a) False negative rates on Test-A across 10 query budgets.\\n0\\n50\\n100\\n150\\n200\\n250\\n300\\n350\\n# Detected Misconfiguration\\n0\\n20\\n40\\n60\\n80\\n100\\nQuery Count\\nTAC\\nTAC-MamlPT\\nTAC-NoPT\\nTAC-EA\\nTAC-RD\\n(b) Query efficiency on Test-A under the query budget of 100.\\nFig. 10. Evaluation results on Test-A. Solid lines represent the mean, and shaded regions indicate the standard\\ndeviation across 11 repeated experiments.\\na query budget of 60, while all greybox variants fail at any budget. In summary, TAC achieves the\\nlowest FNRs on both Test-B and Test-C sets.\\nRQ3: Effectiveness of TAC in query count. To evaluate how our GNN-based RL with pretraining\\nimproves query efficiency, we compare TAC with its greybox variants in terms of query count.\\nFigure10b illustrates the query counts of TAC and its greybox variants under a query budget of 100\\non the Test-A set. For clarity, detected PEs are sorted for each detector by their average query\\ncount, computed from 11 repeated experiments, in ascending order.\\nWe observe that TAC consistently requires significantly fewer queries than its greybox variants\\nto detect the same number of PEs. Conversely, for the same query count, TAC detects far more PEs.\\nSpecifically, TAC detects 362 PEs with an average query count of 19, whereas TAC-NoPT detects only\\n175 PEs with an average query count 1.8 times higher, TAC-MamlPT detects 204 PEs with a count\\n1.7 times higher, TAC-EA detects only 34 PEs with a count 2.2 times higher, and TAC-RD performs\\neven worse than TAC-EA. Moreover, all four variants show much higher standard deviations than\\nTAC. These results underscore the critical role of our GNN-based RL with pretraining in reducing\\nand stabilizing query counts while mitigating negative transfer. In summary, the GNN-based RL\\nwith pretraining is essential for enhancing and stabilizing TAC’s query efficiency.\\n8\\nRelated Work\\nExisting cloud security tools primarily focus on whitebox IAM PE detection, which can be classified\\ninto three categories: reasoning-based approaches, pattern-based approaches, and graph-based\\napproaches.\\n16\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\nFor reasoning-based approaches, Ilia and Oded [44] employ bounded model checking to for-\\nmally verify PEs in IAM configurations, by formulating the problem into SMT formulas and uses\\nSMT solver to solve the formula. Unfortunately, as of submission, the reasoning-based detec-\\ntor is not publicly available, preventing its inclusion as a baseline in our experiments. In the\\npattern-based approach, Gietzen identified 21 typical IAM PE patterns [18]. Tools like Pacu[30] and\\nCloudsplaining[42] leverage these patterns to detect IAM PEs. However, they cannot identify\\ntransitive PEs, where attackers gain permissions indirectly through intermediate entities [2].\\nGraph-based approaches address this limitation. PMapper[19] models authentication relationships\\nbetween users/roles in IAM configurations as directed graphs, enabling the detection of transitive\\nPEs where non-admin users can authenticate as admins. AWSPX[31] extends this by visualizing\\ndetected PEs. However, these methods have two key drawbacks: (1) they focus solely on user/role\\nauthentication, ignoring PEs involving other entity types (e.g., services) or non-authentication\\nstrategies (e.g., changing IAM policy versions [3]); and (2) they overlook PEs arising from sensitive\\npermissions in non-admin entities. In contrast, TAC proposes a more general and flexible graph-\\nbased approach using our permission flow concepts. This enables detection of diverse PE scenarios\\nbeyond authentication chains, including group memberships and role assumption chains, across\\nadmin and non-admin entities. Additionally, TAC’s abstract IAM modeling, built on top of its\\nconcrete modeling, allows detection with partial visible IAM configuration information.\\n9\\nConclusion\\nIn this paper, we presented TAC, an efficient greybox penetration testing approach for third-party\\ncloud security services to detect IAM PEs caused by misconfigurations. Unlike whitebox methods\\nrequiring full anonymization of IAM configurations, TAC selectively queries only essential informa-\\ntion. Leveraging a comprehensive IAM modeling framework and a GNN-based RL approach with\\npretraining, TAC minimizes query usage while detecting a wide range of PEs in partially visible\\nconfigurations. To create diverse and realistic IAM PE benchmarks, we developed IAMVulGen, an\\nIAM PE task synthesizer. Experimental results on synthetic and real-world benchmarks demonstrate\\nthat TAC achieves low, and in some cases even significantly lower, false negative rates compared to\\nstate-of-the-art whitebox approaches.\\nReferences\\n[1] Seth Art. 2021. IAM Vulnerable - An AWS IAM Privilege Escalation Playground. https://bishopfox.com/blog/aws-iam-\\nprivilege-escalation-playground.\\n[2] Seth Art. 2021. IAM Vulnerable - Assessing the AWS Assessment Tools. https://bishopfox.com/blog/assessing-the-\\naws-assessment-tools.\\n[3] AWS. 2023. AWS IAM API Reference: SetDefaultPolicyVersion. https://docs.aws.amazon.com/IAM/latest/APIReference/\\nAPI_SetDefaultPolicyVersion.html.\\n[4] AWS. 2023. AWS Identity and Access Management (IAM). https://aws.amazon.com/iam/.\\n[5] AWS. 2023.\\nAWS Service Authorization Reference: Actions, resources, and condition keys for AWS ser-\\nvices. https://docs.aws.amazon.com/pdfs/service-authorization/latest/reference/service-authorization.pdf#reference_\\npolicies_actions-resources-contextkeys.\\n[6] AWS. 2023. Security best practices in IAM. https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html.\\n[7] AWS. 2023. Testing IAM policies with the IAM policy simulator. https://docs.aws.amazon.com/IAM/latest/UserGuide/\\naccess_policies_testing-policies.html.\\n[8] AWS. 2023. Using AWS IAM Access Analyzer. https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-\\nanalyzer.html.\\n[9] AWS. 2023. What is Amazon Verified Permissions? https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/\\nwhat-is-avp.html.\\n[10] John Backes, Pauline Bolignano, Byron Cook, Catherine Dodge, Andrew Gacek, Kasper Luckow, Neha Rungta, Oksana\\nTkachuk, and Carsten Varming. 2018. Semantic-based automated reasoning for AWS access policies using SMT. In\\n2018 Formal Methods in Computer Aided Design (FMCAD). IEEE, 1–9.\\nEfficient IAM Greybox Penetration Testing\\n17\\n[11] Malik Bouchet, Byron Cook, Bryant Cutler, Anna Druzkina, Andrew Gacek, Liana Hadarean, Ranjit Jhala, Brad\\nMarshall, Dan Peebles, Neha Rungta, et al. 2020. Block public access: trust safety verification of access control policies.\\nIn Proceedings of the 28th ACM Joint Meeting on European Software Engineering Conference and Symposium on the\\nFoundations of Software Engineering. 281–291.\\n[12] Shaked Brody, Uri Alon, and Eran Yahav. 2021.\\nHow attentive are graph attention networks?\\narXiv preprint\\narXiv:2105.14491 (2021).\\n[13] Tom Brown, Benjamin Mann, Nick Ryder, Melanie Subbiah, Jared D Kaplan, Prafulla Dhariwal, Arvind Neelakantan,\\nPranav Shyam, Girish Sastry, Amanda Askell, et al. 2020. Language models are few-shot learners. Advances in neural\\ninformation processing systems 33 (2020), 1877–1901.\\n[14] Myungsik Cho, Whiyoung Jung, and Youngchul Sung. 2022. Multi-task reinforcement learning with task representation\\nmethod. In ICLR 2022 Workshop on Generalizable Policy Learning in Physical World.\\n[15] Cybersecurity Insiders. 2021. Cloud Security Report. https://www.isc2.org/Landing/cloud-security-report.\\n[16] Tristan Deleu and Yoshua Bengio. 2018. The effects of negative adaptation in model-agnostic meta-learning. arXiv\\npreprint arXiv:1812.02159 (2018).\\n[17] Carlo D’Eramo, Davide Tateo, Andrea Bonarini, Marcello Restelli, and Jan Peters. 2024. Sharing knowledge in multi-task\\ndeep reinforcement learning. arXiv preprint arXiv:2401.09561 (2024).\\n[18] Spencer Gietzen. 2018. AWS IAM Privilege Escalation – Methods and Mitigation. https://rhinosecuritylabs.com/aws/\\naws-privilege-escalation-methods-mitigation/.\\n[19] NCC Group. 2023. Principal Mapper. https://github.com/nccgroup/PMapper.\\n[20] Nikolaus Hansen. 2006. The CMA evolution strategy: a comparing review. Towards a new evolutionary computation\\n(2006), 75–102.\\n[21] Yang Hu, Wenxi Wang, Sarfraz Khurshid, Kenneth L McMillan, and Mohit Tiwari. 2023. Fixing Privilege Escalations\\nin Cloud Access Control with MaxSAT and Graph Neural Networks. 104–115 pages.\\n[22] Orca Security Inc. 2024. Thrive Security in the Cloud. https://orca.security/.\\n[23] Sysdig Inc. 2024. Cloud-Native vs. Third-Party Cloud Security Tools. https://sysdig.com/learn-cloud-native/cloud-\\nsecurity/cloud-native-vs-third-party-cloud-security-tools/.\\n[24] Symmetry Systems Inc. 2024. Data Security Posture Management. https://www.symmetry-systems.com/.\\n[25] Wiz Inc. 2024. Secure Everything You Build And Run in the Cloud. https://go.wiz.io/.\\n[26] Eric Kedrosky. 2022. Achieving AWS Least Privilege: Understanding Privilege Escalation. https://sonraisecurity.com/\\nblog/common-methods-aws-privilege-escalation/.\\n[27] Shaharyar Khan, Ilya Kabanov, Yunke Hua, and Stuart Madnick. 2022. A systematic analysis of the capital one data\\nbreach: Critical lessons learned. ACM Transactions on Privacy and Security 26, 1 (2022), 1–29.\\n[28] Gerben Kleijn. 2022. Well, That Escalated Quickly: Privilege Escalation in AWS. https://bishopfox.com/blog/privilege-\\nescalation-in-aws.\\n[29] Manjur Kolhar, Mosleh M Abu-Alhaj, and Saied M Abd El-atty. 2017. Cloud data auditing techniques with a focus on\\nprivacy and security. IEEE Security & Privacy 15, 1 (2017), 42–51.\\n[30] Rhino Security Lab. 2022. Pacu: The Open Source AWS Exploitation Framework. https://rhinosecuritylabs.com/aws/\\npacu-open-source-aws-exploitation-framework/.\\n[31] WithSecure Labs. 2022. A graph-based tool for visualizing effective access and resource relationships in AWS\\nenvironments. https://github.com/WithSecureLabs/awspx.\\n[32] Ilya Loshchilov and Frank Hutter. 2017. Decoupled weight decay regularization. arXiv preprint arXiv:1711.05101\\n(2017).\\n[33] Trend Micro. 2021.\\nThe Most Common Cloud Misconfigurations That Could Lead to Security Breaches.\\nhttps://www.trendmicro.com/vinfo/us/security/news/virtualization-and-cloud/the-most-common-cloud-\\nmisconfigurations-that-could-lead-to-security-breaches.\\n[34] Assaf Morag. 2021. Cloud Misconfigurations: The Hidden but Preventable Threat to Cloud Data. https://www.\\ninfosecurity-magazine.com/opinions/cloud-misconfigurations-threat/.\\n[35] Capital One. 2022. Information on the Capital One Cyber Incident. https://www.capitalone.com/digital/facts2019/.\\n[36] Momen Oqaily, Yosr Jarraya, Meisam Mohammady, Suryadipta Majumdar, Makan Pourzandi, Lingyu Wang, and\\nMourad Debbabi. 2019. SegGuard: segmentation-based anonymization of network data in clouds for privacy-preserving\\nsecurity auditing. IEEE Transactions on Dependable and Secure Computing 18, 5 (2019), 2486–2505.\\n[37] Long Ouyang, Jeffrey Wu, Xu Jiang, Diogo Almeida, Carroll Wainwright, Pamela Mishkin, Chong Zhang, Sandhini\\nAgarwal, Katarina Slama, Alex Ray, et al. 2022. Training language models to follow instructions with human feedback.\\nAdvances in Neural Information Processing Systems 35 (2022), 27730–27744.\\n[38] Cedric Pernetf. 2021. Research reveals that IAM is too often permissive and misconfigured. https://www.techrepublic.\\ncom/article/research-iam-permissive-misconfigured/.\\n18\\nYang Hu, Wenxi Wang, Sarfraz Khurshid, and Mohit Tiwari\\n[39] Nathaniel Quist. 2021. Unit 42 Cloud Threat Report Update: Cloud Security Weakens as More Organizations Fail to\\nSecure IAM. https://unit42.paloaltonetworks.com/iam-misconfigurations/.\\n[40] Michael T Rosenstein, Zvika Marx, Leslie Pack Kaelbling, and Thomas G Dietterich. 2005. To transfer or not to transfer.\\nIn NIPS 2005 workshop on transfer learning, Vol. 898.\\n[41] Jungwoo Ryoo, Syed Rizvi, William Aiken, and John Kissell. 2013. Cloud security auditing: challenges and emerging\\napproaches. IEEE Security & Privacy 12, 6 (2013), 68–74.\\n[42] Salesforce. 2022. Cloudsplaining. https://cloudsplaining.readthedocs.io/en/latest/.\\n[43] Hemani Sehgal. 2021. Cloud Security Conundrum Debunked: Native Vs. Third-Party Tools. https://www.horangi.\\ncom/blog/cloud-security-native-third-party-tools.\\n[44] Ilia Shevrin and Oded Margalit. 2023. Detecting {Multi-Step}{IAM} Attacks in {AWS} Environments via Model\\nChecking. In 32nd USENIX Security Symposium (USENIX Security 23). 6025–6042.\\n[45] Trevor Standley, Amir Zamir, Dawn Chen, Leonidas Guibas, Jitendra Malik, and Silvio Savarese. 2020. Which tasks\\nshould be learned together in multi-task learning?. In International conference on machine learning. PMLR, 9120–9132.\\n[46] Lingfeng Sun, Haichao Zhang, Wei Xu, and Masayoshi Tomizuka. 2022. Paco: Parameter-compositional multi-task\\nreinforcement learning. Advances in Neural Information Processing Systems 35 (2022), 21495–21507.\\n[47] Richard S Sutton and Andrew G Barto. 2020. Reinforcement learning: An introduction. MIT press.\\n[48] Xscaler. 2021. Anatomy of a Cloud Breach: How 100 Million Credit Card Numbers Were Exposed. https://www.zscaler.\\ncom/resources/white-papers/capital-one-data-breach.pdf.\\nEfficient IAM Greybox Penetration Testing\\n19\\nA\\nTask Set Statistics\\nTask Set\\nSource\\n# Task\\n# Entity\\n# Vis Entity\\n# Vis Flow\\n# Permission\\nType\\nmin\\nmax\\navg\\nmin\\nmax\\navg\\nmin\\nmax\\navg\\nPretrain\\nIAMVulGen\\n2,000\\n72\\n2\\n34\\n15\\n2\\n274\\n48\\n6\\n313\\n67\\nTest-A\\nIAMVulGen\\n500\\n72\\n3\\n27\\n14\\n2\\n300\\n70\\n12\\n322\\n72\\nTest-B\\nIAM Vulnerable\\n31\\n11\\n1\\n3\\n2\\n0\\n6\\n2\\n3\\n12\\n7\\nTest-C\\nStartup\\n2\\n8\\n15\\n25\\n20\\n84\\n261\\n172\\n88\\n252\\n170\\nTable 1. Statistics of three PE task sets.\\nTable 1 summarizes the statistics of the task sets we have used for pretraining and evaluating\\nTAC. The Pretrain set includes diverse PE tasks with 72 entity types, 2–34 visible entities, 2–274\\npermission flows, and 6–313 permissions, similar to Test-A. In contrast, Test-B features smaller,\\nless diverse tasks with 11 entity types, 1–3 visible entities, 0–6 permission flows, and 3–12 per-\\nmissions. The Test-C task set includes two real-world misconfigurations, Real-1 (15 entities, 84\\npermission flows, 88 permissions) and Real-2 (25 entities, 261 permission flows, 252 permissions).\\nWhile specific details cannot be disclosed due to data security protocols, both misconfigurations\\nfeature at least one transitive PE with paths of five or more steps, posing significant detection\\nchallenges under a limited query budget.\\n'),\n", - " Document(metadata={'Published': '2011-11-22', 'Title': 'A Theory for Optical flow-based Transport on Image Manifolds', 'Authors': 'Sriram Nagaraj, Aswin C. Sankaranarayanan, Richard G. Baraniuk', 'Summary': 'An image articulation manifold (IAM) is the collection of images formed when\\nan object is articulated in front of a camera. IAMs arise in a variety of image\\nprocessing and computer vision applications, where they provide a natural\\nlow-dimensional embedding of the collection of high-dimensional images. To date\\nIAMs have been studied as embedded submanifolds of Euclidean spaces.\\nUnfortunately, their promise has not been realized in practice, because real\\nworld imagery typically contains sharp edges that render an IAM\\nnon-differentiable and hence non-isometric to the low-dimensional parameter\\nspace under the Euclidean metric. As a result, the standard tools from\\ndifferential geometry, in particular using linear tangent spaces to transport\\nalong the IAM, have limited utility. In this paper, we explore a nonlinear\\ntransport operator for IAMs based on the optical flow between images and\\ndevelop new analytical tools reminiscent of those from differential geometry\\nusing the idea of optical flow manifolds (OFMs). We define a new metric for\\nIAMs that satisfies certain local isometry conditions, and we show how to use\\nthis metric to develop a new tools such as flow fields on IAMs, parallel flow\\nfields, parallel transport, as well as a intuitive notion of curvature. The\\nspace of optical flow fields along a path of constant curvature has a natural\\nmulti-scale structure via a monoid structure on the space of all flow fields\\nalong a path. We also develop lower bounds on approximation errors while\\napproximating non-parallel flow fields by parallel flow fields.'}, page_content='A Theory for Optical flow-based Transport\\non Image Manifolds\\nSriram Nagaraj, Aswin C. Sankaranarayanan, Richard G. Baraniuk\\nRice University\\nAbstract\\nAn image articulation manifold (IAM) is the collection of images formed when\\nan object is articulated in front of a camera. IAMs arise in a variety of image\\nprocessing and computer vision applications, where they provide a natural low-\\ndimensional embedding of the collection of high-dimensional images. To date\\nIAMs have been studied as embedded submanifolds of Euclidean spaces. Un-\\nfortunately, their promise has not been realized in practice, because real world\\nimagery typically contains sharp edges that render an IAM non-differentiable and\\nhence non-isometric to the low-dimensional parameter space under the Euclidean\\nmetric. As a result, the standard tools from differential geometry, in particular\\nusing linear tangent spaces to transport along the IAM, have limited utility. In this\\npaper, we explore a nonlinear transport operator for IAMs based on the optical\\nflow between images and develop new analytical tools reminiscent of those from\\ndifferential geometry using the idea of optical flow manifolds (OFMs). We de-\\nfine a new metric for IAMs that satisfies certain local isometry conditions, and we\\nshow how to use this metric to develop a new tools such as flow fields on IAMs,\\nparallel flow fields, parallel transport, as well as a intuitive notion of curvature.\\nThe space of optical flow fields along a path of constant curvature has a natural\\nmulti-scale structure via a monoid structure on the space of all flow fields along a\\npath. We also develop lower bounds on approximation errors while approximating\\nnon-parallel flow fields by parallel flow fields.\\nKeywords: Image articulation manifolds, Transport operators, Optical flow\\nPreprint submitted to ACHA\\nAugust 24, 2024\\narXiv:1111.5108v1 [cs.CV] 22 Nov 2011\\n1. Introduction\\n1.1. Image articulation manifolds\\nMany problems in image processing and computer vision involve image en-\\nsembles that are generated by varying a small set of imaging parameters such as\\npose, lighting, view angle, etc. of a fixed three-dimensional (3D) scene. As the\\nparameters vary, the images can be modeled as a lying on a (typically nonlinear)\\nmanifold called an image articulation manifold (IAM) [1, 2, 3, 4]. Each point on\\nan IAM is an image at a particular parameter value. Over the past decade, there\\nhas been significant work [3, 5, 6, 7] in learning and processing the underlying\\ngeometric structures associated with image ensembles. For instance, tasks such as\\nrecognition, classification, and image synthesis can be interpreted as navigation\\nalong a particular IAM.\\nMore specifically, we define an image articulation manifold (IAM) as the set\\nof images M formed by the action of an imaging map i on a space of articulations\\nΘ, i.e, M = {iθ = i(θ) : θ ∈Θ}. This imaging process can be decomposed\\ninto two steps: first the action of the articulation on a 3D object or scene and\\nthen the subsequent imaging of the articulated object/scene (see [8] for a detailed\\ndiscussion of image formation).1\\n1.2. IAM Challenges\\nIn spite of much progress, there are fundamental challenges to successfully\\napplying manifold-processing tools to generic image data, in particular IAMs.\\nFirst, it has been shown that IAMs containing images with sharp edges are\\nnon-differentiable [1]. Specifically, given parameters θ1 and θ2 with correspond-\\ning images I1 and I2, it follows that the L2 distance ∥I1 −I2∥L2 between images\\nI1 and I2 is a nonlinear function η(∥θ1 −θ2∥) that is asymptotically equivalent to\\n(∥θ1 −θ2∥)\\n1\\n2. Indeed,\\n∥I1−I2∥L2\\n∥θ1−θ2∥\\n≥c∥θ1 −θ2∥−1\\n2, and this non-Lipschitz relation\\n1Before we proceed further, it is worth discussing certain degeneracies in the imaging process\\nthat we wish to avoid in this paper for analytical reasons. In particular, we want to avoid cases\\nwhere the set M is not expressive of the full range of articulations. As an example, consider a\\nuniformly colored 3D sphere O undergoing rotation about a fixed axis. Here, the parameter space\\nΘ is the unit circle S1. Being uniformly colored, the sphere does not change appearance under\\nrotation, and the IAM degenerates to a single point {IO}. Were the sphere richly textured, we\\nwould obtain new views of the sphere for each rotation so that the IAM is isomorphic to S1. For\\nthe remainder of the paper, we will consider IAMs without degeneracies by assuming that the\\nimaging map i is a re-parametrization of Θ; i.e., we will assume that the IAM is homeomorphic to\\nthe corresponding parameter space.\\n2\\nI1 \\nLinear path α(t) \\n \\nI2 \\nIAM \\nI1 \\nI2 \\nFigure 1: Non-differentiability of IAMs renders (locally) linear transport inaccurate. Consider an\\nimage interpolation task. Given images I1 and I2, the line connecting them α(t) = tI1 +(1−t)I2\\nis blurred and thus a poor approximation to the geodesic connecting I1 and I2.\\nindicates that the corresponding IAM is non-differentiable. Non-differentiability\\nsuggests that local linear approximations, such as those suggested by differential\\ngeometry, are invariably inaccurate on IAMs. To illustrate this, consider a stylized\\nexample of image interpolation (see Fig. 1). Given images I1, I2 ∈M, consider\\nthe affine path α(t) = tI1+(1−t)I2 with t ∈[0, 1]; for a smooth manifold (> C2),\\nthis line would be a close approximation to the actual manifold, especially over\\nsmall neighborhoods. However, non-differentiability implies that a first-order ap-\\nproximation to the manifold is inaccurate even over a small neighborhood. This is\\nillustrated in Fig. 1. To alleviate the non-differentiability problem, Wakin et al. [2]\\nhave proposed a multiscale smoothing procedure that regularizes each point of the\\nIAM by a set of multiscale Gaussian smoothing filters that render the IAM smooth\\nacross the various scales. This smoothing procedure then enables the definition of\\nlinear tangent spaces on which one can perform standard linear methods of analy-\\nsis. However, this is unsatisfactory, since Gaussian smoothing is inherently lossy\\n— leading to loss of high-frequency information in the images. Further, defining\\ntangent vectors as the limit of a multiscale procedure is inherently complex and\\nmoreover not possible for practical scenarios where we have only samples from\\nthe IAM.\\nSecond, conventional manifold models lack a meaningful metric between\\npoints on the IAM, especially when the sampling of the manifold is sparse. Con-\\nsider the simple translation manifold MT generated by imaging a black disk of\\nradius R translating on an infinite white background (see Fig. 2). Let I1 be the\\nimage of the disk with center c1 and I2 the image of the disk with center c2. It\\n3\\nc2\\n(a) Image I1\\n(b) Image I2\\n(c) Image I3\\n(d) Image I4\\n0\\n20\\n40\\n60\\n80\\n100\\n0\\n0.5\\n1\\n1.5\\n2\\n2.5\\n3\\n3.5\\nTranslation θ in [px]\\nEuclidean distance\\n(e) Distance function \\n||)\\n(|| c\\n∆\\nη\\n2R\\nI1\\nI2\\nI4\\nI3\\nFigure 2: Euclidean distance between images on an IAM can be meaningless. (a-d) Images of a\\ntranslating disk over a white background. (e) The L2 distance between two images depends on the\\namount of overlap between the the disks. However, the overlap is zero when the distance between\\ncenters exceed 2R; in the figure above, d(I1, I3) = d(I1, I4). Hence, the distance between two im-\\nages can be written as η(min(2R, ∥c1 −c2∥2)) where η(·) is a monotonically increasing function.\\nConventional manifold learning techniques, which rely heavily on meaningful local distances, do\\nnot work unless the sampling on the manifold is dense.\\nthen follows that\\n∥I1 −I2∥L2 = η(min(2R, ∥c1 −c2∥)) =\\n(\\nη(∥c1 −c2∥),\\n∥c1 −c2∥< 2R\\nη(2R),\\n∥c1 −c2∥≥2R\\nwhere η(·) is a nonlinear function. Thus, when the disk centers are separated by\\na distance greater than the diameter of the disk, the metric is completely unin-\\nformative (see Fig. 2). This suggests that, unless the sampling of images from\\nthe IAM is sufficiently dense, organization of the images using a construct such\\nas a k-nearest neighbor graph is meaningless. k-nearest neighbor graphs are at\\nthe heart of traditional manifold learning techniques such as LLE [6], ISOMAP\\n[5], and diffusion maps [3]; as a consequence, such techniques are doomed to fail\\nunless the sampling is sufficiently dense.\\nThese shortcomings are exacerbated for images with rich textures; this rules\\nout a consistent analysis of IAMs based on classical differential geometry that\\n4\\nrelies on the smoothness and metric properties of the manifold. A critical missing\\nlink in the analysis of IAMs is a systematic theory that successfully handles the\\nabove issues and permits new mathematical tools for IAMs, including analogues\\nof traditional notions such as curvature, vector fields, parallel transport, etc. [9].\\nClearly, once such analytic tools are available, we can greatly expand the scope of\\napplications and pave the way for efficient algorithms specific to IAMs.\\n1.3. Transport operators\\nRecently, a new class of methods for handling image ensembles has been de-\\nveloped based on the idea of transport operators [4, 10, 11, 12, 13]. A transport\\noperator on an IAM is a (typically nonlinear) map from the manifold into itself\\nthat enables one to move between different points on the manifold. Given im-\\nages I1(x) and I2(x), (where I(x) denotes the intensity at the spatial location\\nx = (x, y) ∈[0, 1] × [0, 1]) a transport operator T is a mapping that acts in the\\nfollowing fashion:\\nI2(x) = I1(x + T(x)).\\n(1)\\nInstead of relying on the linear tangent space that accounts only for infinitesi-\\nmal transformations, nonlinear transport operators can be well-defined over larger\\nregions on the IAM.\\nFor certain classes of articulations, the associated transport operators have al-\\ngebraic structure in the form of a Lie group [11, 10, 12, 4]. In such instances, it\\nis possible to explicitly compute transport operators that capture the curved geo-\\nmetric structure of an IAM. An example of this is the case of affine articulations,\\nwhere the transport takes the form\\nI(x) = I0(Ax + t).\\nIn this case, the transport operator T(·) is of the form T(x) = (A −I)x + t; this\\ncan be modeled as the group of 2D affine transformations. The affine group has\\nfound extensive use in tracking [12] and registration [14]. Miao and Rao [10] learn\\naffine transport operators for image ensembles using a matrix exponential-based\\ngenerative model and demonstrate improved performance over locally linear ap-\\nproximations. Culpepper and Olshausen [4] extend this framework using a more\\ncomplex model on the transport operator in order to model paths on image mani-\\nfolds.\\nOther common examples of articulations in computer vision are the projective\\ngroup (used to model homographies and projective transformations) and diffeo-\\nmorphisms (used to model 1D warping functions, density functions) [15]. How-\\n5\\never, while algebraic transport methods are mathematically elegant, they are appli-\\ncable only to a very restrictive class of IAMs. Many IAMs of interest in computer\\nvision and image processing applications, including IAMs corresponding to 3D\\npose articulations and non-rigid deformations, possess no explicit algebraic struc-\\nture.\\n1.4. Optical flow-based transport\\nIn this paper, we study a specific class of transport operators that are generated\\nby the optical flow between images (we introduced this notion empirically in [13]).\\nGiven two images I1 and I2, the optical flow between them is defined to be the\\ntuple (vx, vy) ∈L2([0, 1]2) × L2([0, 1]2) such that\\nI2(x, y) = I1(x + vx(x, y), y + vy(x, y)).\\n(2)\\nA common assumption in computing the optical flow between images is bright-\\nness constancy [16], where the spatial intensity is assumed to not change between\\nI1 and I2. Since the pioneering work of Horn and Schunk [16], there has been\\nsignificant progress towards the robust estimation of optical flow between image\\npairs [17, 18].\\nOptical flow is a natural and powerful transport operator to transform one im-\\nage into another. In the context of image manifolds, the collection of all optical\\nflow operators at a point on an IAM is a manifold of the same dimension as the\\nIAM [13]. In other words, at any reference image on an IAM, there is a corre-\\nsponding manifold of optical flow operators that transports the reference image\\nalong the IAM. This new operator manifold, which we christen the optical flow\\nmanifold (OFM), can be used to obtain a canonical chart for the IAM [13]; this\\nenables significantly improved navigation capabilities on the IAM than previous\\nmethods. In particular, OFM-based transport is well-defined even in instances\\nwhen the transport operators cannot be modeled as a Lie group; an example of\\nthis is the pose manifold (the IAM associated with rigid body motion).\\nTo see the efficacy of optical flow-based transport, consider again the case of\\nimage interpolation, but now with optical flow as the transport operator (see Fig.\\n3). Here, the path γ(t), t ∈[0, 1] generated on the IAM via optical flow is a better\\nrepresentative of a path on the IAM, i.e., γ(t) ∈M for all t. Moreover, if the IAM\\nis generated via Lie group actions, then this path coincides with the geodesic.\\nAs discussed earlier, IAMs composed of images with sharp edges and textures\\nlack smoothness and hence do not support locally linear modeling. In contrast,\\nfor a large class of interesting articulations, including affine transformations and\\n6\\nNonlinear path \\nγ(t) \\nI1 \\nI2 \\nIAM \\nI1 \\nI2 \\nFigure 3: Optical flow based transport on an IAM leads to accurate image interpolation. Consider\\nagain the interpolation task in Fig. 1. While locally linear transport on IAMs lead to inaccurate\\ninterpolation results, the path γ(t) generated using optical flow provides an accurate approximation\\nto the true path between I1 and I2. Moreover, if the IAM is generated via Lie group actions, then\\nthe path generated coincides with the geodesic.\\n3D pose, the corresponding OFMs are smooth (see Appendix A and [13]) and\\nsupport local linear modeling. Moreover, we can define the distance between\\ntwo optical flows to measure the amount of motion required to articulate from\\none image to another. These properties suggest that machine learning techniques\\n(such as LLE, ISOMAP, etc.) should be able to extract a considerable amount\\nof geometrical information about an image ensemble when applied to its OFMs.\\nFigure 4 confirms this fact by showcasing the improvement in OFM vs. IAM-\\nbased dimensionality reduction for an object under 2D translation.\\nThe stability of OFM-based modeling enables us below to develop new dif-\\nferential geometric tools for signal processing such as the geometric mean and\\nKarcher mean [19] of an image ensemble. The Karcher mean of a set of images is\\ndefined as the image on the IAM that is closest to the set in the sense of geodesic\\ndistance. Figure 5 shows the results of Karcher mean estimation using the OFM.\\nThe interested reader is referred to [13] for details of the Karcher mean estimation\\nas well as more OFM-based tools and applications.\\n1.5. Related work\\nOFMs fall under the category of deformation modeling, which has been stud-\\nied in many different contexts, including active shape [20] and active appearance\\nmodels [21]. However, there are significant differences between OFMs and tra-\\nditional deformation modeling approaches. Morphlets [22], for examlpe, provide\\na mutliscale modeling of and interpolation across image deformations, but their\\n7\\n(a) Images\\n(b) Ground t ruth\\n(c) IAM (d) OFM\\nFigure 4: Comparison of manifold learning on a IAM vs. OFM (from [13]). The IAM is generated\\nby cropping patches of size 200×200 pixels at random from an image — thereby generating a 2D\\ntranslation manifold. (a) Sample images from the IAM showing a few images at various transla-\\ntions. (b-d) 2D embedding obtained using ISOMAP on (b) the ground truth, (c) the IAM, and (d)\\nthe OFM. The near perfect embedding obtained using OFM hints at the near-perfect isometry in\\nthe OFM distances.\\ntreatment is limited to image pairs. In contrast, OFMs apply to image ensembles\\nconsisting of a potentially large number of images. Beymer and Poggio [23] have\\nargued for the use of motion-based representations for learning problems. How-\\never, their goal is image synthesis, and therefore they offer no insights into the\\ngeometric nature of manifold-valued data. Jojic et al. [24] use a layered represen-\\ntation to represent videos by separating the appearance of moving objects from\\ntheir motion and then representing each using subspace and manifold models,\\nrespectively. This simple, yet powerful, representation can model and synthesize\\ncomplex scenes using simple primitives, but it is not intended to go beyond simple\\nmanifolds such as those generated by translations and affine transformations.\\n1.6. Specific contributions\\nThe main aim of this paper is to develop the mathematical foundation of op-\\ntical flow-based transport operators for image manifolds, which were introduced\\nempirically [13].\\nWe first define a metric on an IAM using its corresponding OFMs. Each OFM\\n8\\n(a) Sampling of images from an IAM \\n(d) OFM-based \\nKarcher mean \\n(c) IAM-based \\nKarcher mean \\n(b) Ground truth \\nFigure 5: Karcher mean estimation for 20 images generated by the rotation of an object about a\\nfixed axis [13]. The images are from the COIL dataset [25]. (a) Sample images from the IAM\\nshowing a few images at various rotations. We estimate the Karcher mean using local linear trans-\\nport on the IAM and the OFM. Shown above are (b) the ground truth Karcher mean of the images,\\n(c) the Karcher mean estimated using local linear transport on the IAM, and (d) the Karcher mean\\nestimated using local linear transport on the OFM. The accuracy of the estimate obtained from the\\nOFM showcases the validity of local linear transport on the OFM.\\nhas a natural metric that is a locally isometric function of the corresponding pa-\\nrameter values. We consider the induced metric on the IAM, which we dub the\\nflow metric and show that the flow metric between two points of the IAM is a\\nmeasure of the distance between the corresponding parameter values. Next, us-\\ning the flow metric, we develop analytic notions of curvature, optical flow fields,\\nand parallel transport. We analyze in detail the case of optical flow fields defined\\nalong a fixed curve. In particular, we define a unique function associated to each\\nsuch flow field, which we dub the motion function, using which we can define\\nthe notion of parallel flow fields. We answer the natural question of how one can\\noptimally approximate a non-parallel field by a parallel field, and thereby induce\\nuniform motion along the curve. We also construct a monoid structure on the set\\nof all flow fields along a fixed curve. Under certain conditions on the curvature of\\na curve, we show that the space of parallel optical flow fields along the curve is a\\nsubmonoid that comes with a convenient multi-scale structure.\\nWe envision that the theory developed in this paper will enable a large class\\nof practical applications involving image manifolds especially under sparse sam-\\npling of images from the manifold. In this context, we believe that the long term\\nimpact of this paper is the first step towards a complete theory of manifolds for\\narbitrary classes of signals using transport operators along the lines of the classic\\n9\\ndifferential geometry for smooth manifolds.\\n1.7. Organization\\nThe remainder of the paper is organized as follows. In Section 2, we introduce\\nOFMs and, using a fixed metric on the OFMs, study the induced flow metric on\\nthe corresponding IAM. We compare dimensionality reduction techniques on the\\nIAM vs. OFMs. Using the flow metric, we develop geometric tools on the IAM in\\nSection 3 and highlight their application to parameter estimation. We also develop\\nerror bounds on approximating non-parallel flow fields by parallel flow fields and\\nillustrate the idea with the example of video resampling. In Section 4 we develop\\nthe multiscale structure of parallel flow fields. We conclude in Section 5 with a\\nbrief discussion.\\n2. OFMs and the Flow Metric\\nIn this section, we define and study the basic properties of OFMs correspond-\\ning to an IAM M. Much of the section is concerned with a formal introduction to\\nOFMs, first defined in [13], leading towards the development of our fundamental\\ntool, the flow metric on an IAM.\\n2.1. Optical flow manifolds\\nThe optical flow between two images on an IAM measures the apparent mo-\\ntion between the two images and thus reflects the corresponding parameter change\\nbetween the two images. For a fixed base image m ∈M, consider a neighbor-\\nhood N(m) of m. If for m′ ∈N(m) there exist flow vectors (vx, vy) such that m′\\ncan be obtained from m using the flow vector, i.e., m′(x, y) = m(x + vx, y + vy),\\nthen we say that optical flow exists from m to m′. We denote this situation as\\nφvx,vy(m) = m′ or simply φ(m) = m′. In practice, occlusion or boundary effects\\n(i.e., veiling of certain portions of an image due to changes in the background\\nor interferers in the scene) may lead to undefined estimates for the flow vectors.\\nHowever, as described in [13], one can mitigate these issues by incorporating\\nadditional consistency tests to ensure that only the meaningful flow vectors are\\nretained.\\nThe set of all points m′ ∈M for which optical flow from m ∈M to m′ exists\\nis a neighborhood of m, which we denote by\\nBm = {m′ ∈M : m′(x, y) = m(x + vx, y + vy)}.\\nUsing this neighborhood, we define the optical flow manifold Om at m as follows.\\n10\\nDefinition 2.1. Let M be a K-dimensional IAM. Given m ∈M, the Optical Flow\\nManifold Om is defined as the set of optical flows φ between m and points in Bm\\nOm = {φ = (vx, vy) : φ(m) ∈Bm}.\\nThe neighborhood Bm is called the flow neighborhood around m.\\nOm is nonlinear, i.e., an arbitrary OFM is not always a linear vector space. It\\nis clear that the collection of neighborhoods {Bm : m ∈M} covers M.\\nProposition 2.2. Let M be a K-dimensional IAM. Then Om has the structure of\\na manifold homeomorphic to Bm.\\nProof. We first show that Om is homeomorphic to Bm and pullback the smooth\\nstructure of Bm to induce a smooth structure on Om. Consider the map g : Bm →\\nOm that sends a point m′ ∈Bm to φ ∈Om such that φ(m′) = m. g is clearly\\nbijective and hence, we use g to endow Om with the quotient topology. Moreover,\\nsince g is injective, g is a homeomorphism since g is an open map: given an open\\nset U ⊂Bm we have U = g−1(g(U)) and by the quotient topology on Om, we\\nhave that V = g(U) is open in Om since g−1(V ) = U is open in Bm. Since\\n{Bm : m ∈M} is a chart for the manifold structure of M, there exists continuous\\nmaps {Φm : m ∈M} so that {(Bm, Φm) : m ∈M} is an atlas for M. Therefore,\\nthe composition Φm ◦g−1 is a homeomorphism from Om to an open set W in RK.\\nSince Om is now covered by the single chart {Om, Φm◦g−1}, we can pullback this\\nsmooth to Om via Φm ◦g−1 and endow Om with a smooth structure. Moreover,\\nBm is homeomorphic to Om by construction.\\nWe make a few preliminary observations. First, by the homeomorphic re-\\nlationship between Om and Bm, we conclude that Om is also a K-dimensional\\nmanifold. Also, Om1 is homeomorphic to Om2 for any m1, m2 ∈M. Moreover,\\nthe trivial element φ0 ∈Om for each m ∈M that maps m to itself in Bm acts a\\nnatural “origin” in Om.\\nWe observe, again from the homeomorphic relationship between Bm and Om,\\nthat given any point m1 ∈Bm there is a unique operator φ1 such that φ1(m) = m1.\\nA question to ask is whether there is any relationship between Om and the tangent\\nspace Tm at m. Indeed, for a smooth IAM, one can define tangent spaces Tm at\\nm ∈M and the OFM Om at m is diffeomorphic to a neighborhood of 0 ∈Tm. To\\nsee this fact, recall that the exponential map defined on Tm is a diffeomorphism\\nbetween a neighborhood U0 of 0 ∈Tm and a neighborhood of Vm of m. We also\\nhave a diffeomorphism Φ from Om to Bm by definition. Now, Bm is open and\\n11\\nthere is an open ball B0 ⫅U0 on which Φ−1 ◦exp is a diffeomorphism, being a\\ncomposition of two diffeomorphisms.\\nAs a concrete example, consider again the translational manifold MT from\\nSection 1.2. Note that the parameter space in this case is Θ = R2. Since there is no\\nocclusion between any two images on MT, it follows that given any m, m′ ∈MT,\\nthere exists a φ ∈Om such that φ(m) = m′. Since this is true for any pair of\\nimages in MT, we conclude that Om = R2 ∀m ∈MT and hence, Bm = MT\\n∀m ∈MT. More generally, we note that for an IAM M generated by Lie group\\nactions without occlusion between images, the OFM Om at any point m ∈M can\\nbe identified with the parameter space Θ and neighborhood Bm at each point is\\nthe entire manifold M. In particular, one can recover the geodesic path between\\ntwo any two points m, m′ ∈M by using appropriate flow operators in Om to\\ngenerate the geodesic path from m to m′. This shortest path corresponds to the\\ngeodesic in the parameter space between the parameter values corresponding to\\nm, m′ as well. We will return to this example in future sections and show how our\\nmore general formulation contains the algebraic methods such as [11, 10, 12, 4]\\nas special cases.\\nAs in the case of the tangent bundle, we can construct an analogous bundle\\nwith the collection of Om since m varies through M.\\nDefinition 2.3. Let M be an IAM and Om the OFM at m ∈M. The flow bundle\\nOM on M to be the disjoint union of the Om since m varies over M\\nOM =\\na\\nm∈M\\nOm.\\nThus, an element of OM is a pair (m, φ) with φ ∈Om. Using this fact, we\\ncan induce a topology on the flow bundle.\\nProposition 2.4. Given a K-dimensional IAM M, the flow bundle OM is a 2K-\\ndimensional manifold.\\nProof. We first note that if (m, φ) ∈OM then {m, φ(m)} ∈{m} × Bm. Thus,\\ngiven an atlas {(Uλ, ψλ)}λ∈Λ of M, we have that\\nψ∗\\nα,β((m, φ)) = (ψα(m), ψβ(φ(m)))\\nmaps (m, φ) into ψα(Uα) × ψβ(Uβ\\nT Bm) where Uα and Uβ are charts around\\nm and φ(m) respectively. The (continuous) inverse of {x1, ..., xk, y1, ..., yk} ∈\\nψα(Uα) × ψβ(Uβ\\nT Bm) is given by (m, φ) where ψα(m) = {x1, ..., xk} and φ\\nis the unique operator in Om such that ψβ(φ(m)) = {y1, ..., yk} so that OM is\\nlocally Euclidean.\\n12\\nThus, we see that OFMs are manifolds consisting of flow operators that are\\ndefined pointwise on the corresponding IAM. The action of flow operators at a\\nbase point on the IAM results in motion along the IAM, as opposed to linear\\ntransport that results in motion off the manifold.\\nThe key property that makes the study of OFMs interesting is that, for interest-\\ning IAMs, the associated OFMs are smooth and exhibit nice distance properties\\n[13]. We summarize these in Appendix A. These two properties, namely smooth-\\nness and isometry, are in turn used to define a meaningful distance on the IAM.\\nWe discuss this next.\\n2.2. Metric structure on an IAM via its OFMs\\nConsider again the translational manifold MT, where the OFM Om at each\\npoint m ∈MT can be identified with R2. Being isometric with R2, we can endow\\neach Om with the Euclidean metric which we denote as dO(·, ·). Let θ1, θ2 ∈R2\\nbe a pair of parameters such that m1 = i(θ1), m2 = i(θ2); note that there exists\\na φ ∈Om1 such that φ(m1) = m2. It then follows that dO(φ0, φ) = C∥θ1 −θ2∥\\nfor some C > 0. As the results of [13] indicate, the above discussion holds\\nanalogously for generic OFMs, i.e., each Om has an associated metric dO(·, ·) and\\nthis metric is locally isometric to a corresponding metric on the parameter space\\nΘ. We indicate this as\\ndO(φ0, φ) ∝dΘ(θ1, θ2),\\nwhere φ0 is the unique operator in Om1 such that m1 = φ0(m1).\\nOur main focus in the remainder of this section is to define a corresponding\\nmetric for IAMs using the metric dO(·, ·) on Om. The resulting metric on M\\ninherits the property of being locally isometric to the changes in parameters. As\\na first step, we locally “push forward” the metric on Om onto Bm as follows.\\nFor points m1, m2 ∈M with m2 ∈Bm1, we have a unique operator φ1 such that\\nm2 = φ1(m1) so that we can define the distance dM(m1, m2) as the corresponding\\ndistance between φ0 and φ1\\ndM(m1, m2) := dO(φ0, φ1).\\nMoreover, if m1 = f(θ1) and m2 = f(θ2) for parameters θ1, θ2 ∈Θ then we have\\ndM(m1, m2) ∝dΘ(θ1, θ2).\\nHowever, this definition does not readily extend to the case where m1 and m2 are\\nnot “optically related”, i.e., m2 /∈Bm1. In this case, we first connect m1 and m2\\n13\\nby a path c such that c(0) = m1, c(1) = m2. We then partition the domain of c by\\na partition P = {0 = t0 < t1 < · · · < tn = 1} such that the intermediate points\\nalong the path are optically related i.e., c(ti) ∈Bc(ti−1), where we assume that, for\\na fine enough partition, we can obtain such a nesting. We then define the distance\\nalong c to be\\nd(c, m1, m2) = sup\\nP\\nn−1\\nX\\ni=0\\ndM(c(ti), c(ti+1)),\\nwhere the supremum is over all partitions of the path.By taking the infimum over\\nall possible paths, we obtain a metric on M, i.e.,\\ndM(m1, m2) = inf\\nc\\nn−1\\nX\\ni=0\\ndM(c(ti), c(ti+1)).\\n(3)\\nIn essence, the metric dM(·, ·) is similar to the Riemannian distance: we first\\ndefine distance over a fixed curve and then take the infimum over all possible\\npaths (see Fig. 6).\\nProposition 2.5. For an IAM M, the distance dM(·, ·) in (3) is a metric on M.\\nProof. Positivity of dM(·, ·) is clear, as is the fact that dM(m, m)\\n=\\n0.\\nIf m1\\n̸=\\nm2, then for every path c between m1 and m2, we have that\\nn−1\\nX\\ni=0\\ndM(c(ti), c(ti+1)) ̸= 0 and hence, dM(m1, m2) ̸= 0.\\nSymmetry follows\\nfrom the fact that along c, c(ti) ∈Bc(ti−1) and hence, dM(c(ti), c(ti+1)) =\\ndM(c(ti+1), c(ti)). For the triangle inequality, we note that given paths c1 and\\nc2 from m1 to m2 and m2 to m3 respectively, the path c1 ∗c2 obtained by\\ntraversing c1 and c2 in succession at twice the rate (i.e. c1 ∗c2(t) = c1(2t) for\\n0 ≦t ≦1\\n2 and c1 ∗c2(t) = c2(2t −1) for 1\\n2 ≦t ≦1) is a path from m1 to m3\\nand\\nn−1\\nX\\ni=0\\ndM(c1(ti), c1(ti+1)) +\\nn−1\\nX\\ni=0\\ndM(c2(ti), c2(ti+1)) ≧\\nn−1\\nX\\ni=0\\ndM(c1 ∗c2(ti), c1 ∗\\nc2(ti+1)). By taking the infimum over all such paths, we verify the triangle in-\\nequality.\\nRecall that the metric on Om satisfies dO(φ0, φ) ∝dΘ(θ1, θ2) with φ ∈Om\\nand θ1, θ2 the parameters corresponding to m and φ(m) respectively. From the\\nabove result, we see that, with the metric dM(·, ·) on M, we have\\ndM(m1, m2) ∝dΘ(θ1, θ2),\\n14\\nm\\nIAM\\nOptical \\nNeighborhoods Bm\\nm1\\nm2\\nc (t)\\nPiecewise distance \\ndM(c(ti),c(ti+1))\\nFigure 6: A pictorial representation of the OFMs and the flow metric for an IAM. Each OFM is\\nmapped homeomorphically onto the flow neighborhood Bm of the corresponding base point. The\\noptical flow distance between two points is computed by considering the infimum over all possible\\ncurves of the piecewise flow distance dM(c(ti), c(ti+1)).\\nwhere m1 and m2 are points on M corresponding to the parameter values θ1 and θ2\\nrespectively under the assumption that the monotonicity of dO(·, ·) over different\\n{Om} is universal, i.e., the distance between two points m1 and m2 does not\\nchange when we change our definitions of flow neighborhoods. We refer to this\\nmetric on M as the flow metric. We note that the flow metric is dependent on the\\nOFMs Om. We can now state the main result of this section.\\nTheorem 2.6. Let M be an IAM and let dM(·, ·) be the associated flow metric.\\nThen, dM(m1, m2) ∝dΘ(θ1, θ2) as defined in (3) with m1 and m2 points on M\\ncorresponding to the parameter values θ1 and θ2 respectively.\\nThe smoothness of the OFMs makes them amenable for use with conventional\\nmanifold processing tools. For instance, common dimensionality reduction meth-\\nods such as [5, 6, 7], etc. assume that the manifold is smooth and, hence, are tools\\nthat are more appropriate for use with the flow metric. As an example, consider\\nFig. 4. Here, we see that the pairwise flow metric between points varies smoothly,\\nas opposed to the Euclidean metric on the IAM, where due to sharp edges, the\\nmatrix of pairwise distance has large off-diagonal entries. Moreover, the resid-\\nual error of non-linear dimensionality reduction using the flow metric decays very\\n15\\nrapidly. As a result, it is more tractable to analyze IAMs using the flow metric as\\nopposed to the conventional Euclidean metric.\\nAs an example, consider the problem of estimating θ ∈Θ such that i(θ) = m\\ngiven a finite number of template points m1, · · · , mn ∈M with neighborhoods\\nBm1, · · · Bmn that cover M. As a motivating special case, consider first the sit-\\nuation when M = MT, the translational manifold with Θ = R2 and a single\\ntemplate point m′. A similar problem has been dealt with in [10, 4] where the\\nauthors estimate the Lie group generators corresponding to the IAM. Given the\\nparameter value θ′ = (c′\\n1, c′\\n2) of the base image m′, we can compute the the pa-\\nrameter θ corresponding to m as follows. First, we find the unique flow operator\\nφ = (φ1, φ2) ∈R2 such that φ(m′) = m. The parameter value θ corresponding to\\nm is then obtained as θ = (c′\\n1 + φ1, c′\\n2 + φ2).\\nAn entirely similar result holds for generic IAMs generated by Lie group ac-\\ntions. From this simple example, we see that finding the optimal θ is equivalent to\\nfinding the optimal flow operator φ that minimizes dM(φ(m′), m) with φ ∈Om′.\\nWe return to the general case with n template images and seek the op-\\ntimal flow operator φ ∈Omi that minimizes dM(φ(mi), m), i = 1, · · · , n.\\nHere, a single neighborhood does not cover the entire IAM, and, hence, to es-\\ntimate φ we first find the neighborhood B ˜m ∈{Bm1, · · · Bmn} such that ˜m =\\narg minm′∈{m1,··· ,mn} dM(m, m′). Our search is then restricted to the neighbor-\\nhood B ˜m. Within this neighborhood, we find the optimal φ ∈O ˜m as above, i.e.,\\nφ = arg min˜φ∈O ˜\\nm dM(˜φ( ˜m), m). In essence, we first find the optimal template\\npoint and then search within the corresponding OFM for the optimal flow opera-\\ntor. If a single template point generates the entire IAM, then this procedure clearly\\nreduces to the Lie group case discussed earlier. We thus see that the generic OFM\\nformulation includes the algebraic methods of [10, 12] as a special case.\\nThe remainder of the paper is devoted to developing geometric tools for IAMs\\nthat leverage the flow metric. Note that, unlike the tangent space, the OFM has no\\nlinear structure and, hence, we do not have at our immediate disposal tools such\\nas parallel translation, covariant derivatives etc. We will construct analogous tools\\nfor our purposes via the flow metric and hence open up a vista for IAM analysis.\\n3. Geometric Tools for IAMs via the Flow Metric\\nIn this section, we develop the basic tools needed to analyze the structure\\nof IAMs using the flow metric. We will pay special attention to flow operators\\ndefined along curves on the corresponding IAMs. Keeping computations in mind,\\n16\\nthese tools will open the door to a variety of applications as mentioned in the\\nIntroduction and beyond.\\n3.1. Flow radius\\nWe first seek an appropriate measure of the size of an OFM and the corre-\\nsponding flow neighborhood. In classical differential geometry, one measures the\\nradius at a point in terms of the injectivity radius [9] using the Riemannian metric.\\nIn a similar fashion, we will measure the radius of a point m in an IAM M in\\nterms of the flow metric.\\n3.1.1. Flow Radius at m ∈M\\nDefinition 3.1. Given an IAM M and m ∈M define the flow radius or simply the\\nradius rm at m as\\nrm = sup\\nn∈Bm\\ndM(m, n).\\nNote that we may regard rm as a function from M to R+ i.e. r(m) = rm is a\\nmap from M into the non-negative reals. Moreover, it is continuous as a function\\nof m. Consider the variations of rm as m varies. If rm is large, then one can find\\na suitable operator φ ∈Om that transports m to a far away point, with distance\\nmeasured using the flow metric. Conversely, a small rm indicates that m can only\\nbe transported within a small region, or said differently, m obstructs transport on\\nthe IAM. Moreover, rapid changes in the magnitude of rm within a small neigh-\\nborhood indicate that the manifold is not well-behaved near m. In particular, this\\nindicates that there are several points close to m that obstruct transport while there\\nare also several points that allow flow over large distances on the IAM.\\n3.1.2. Flow radius for Lie groups\\nA class of IAMs for which rm is very well behaved, indeed for which rm is\\na constant, are those generated by a Lie group action. As a motivating example,\\nconsider again the translational manifold MT. We note that as Om = R2 for each\\nm ∈MT, it follows that rm = ∞. If the parameter space Θ is compact, for\\ninstance, if Θ = S1 and we consider affine rotations of a base image m generating\\nthe IAM M, then we again have that Bm = M and rm is a constant 0 < c < ∞.\\nFor a generic IAM M generated by Lie group actions with Bm = M, it follows\\nthat the flow radius is a constant whose exact value depends both on the object\\nbeing imaged as well as the nature of the articulation.\\n17\\n3.1.3. Flow curvature\\nThe above discussion indicates that the reciprocal\\n1\\nrm is a measure of “curva-\\nture”. When rm is large (or infinite), then the IAM is can be thought as being\\n“optically flat” at m in the sense that there is no obstruction to transport on the\\nmanifold at m. In the other limiting case, i.e., if rm approaches zero, the only\\noperator in Om is the trivial operator φ0 and hence, M is has high “curvature” at\\nm. We thus have the following definition.\\nDefinition 3.2. Given an IAM M and m ∈M define the flow curvature or simply\\nthe curvature at m as Km =\\n1\\nrm.\\nWhile the traditional notion of curvature is a point property, the flow curvature\\ndepends on both the base point as well as its neighborhood properties. In terms\\nof flow curvature, we can now state that if M is generated by a Lie group then\\nM has constant curvature. The class of IAMs with constant curvature will play a\\nprominent role in our later analysis.\\n3.2. Optical flow fields\\nIn this section, we focus on a construct motivated by differential geometry,\\nnamely the idea of a vector field on a manifold. Recall that a vector field is a\\nsection of the the tangent bundle, i.e., a vector field is a map σ : M →TM such\\nthat π ◦σ = idM, where π is the natural projection from the tangent bundle and\\nidM is the identity map on M. In an analogous fashion, we define an optical flow\\nfield, or simply a flow field, as a section of the optical flow bundle of M.\\nWhile vector fields are defined generically on manifolds, the special class of\\nvector fields along curves is especially important in differential geometry. Vector\\nfields along curves give rise to tools such as parallel translation, Jacobi fields, etc.\\n[9]. In the case of IAMs, which lack analytic structure in general, we will define\\noptical fields along curves on an IAM and recover similar geometric tools using\\nthe flow metric. As we assign operators to points on the curve, we intuitively\\nwould like the transport induced by the operator to remain along the curve so that\\nthe collection of flow operators induces motion along the curve. This special class\\nof optical fields will be our main object of study for the rest of the paper.\\nDefinition 3.3. Let M be an IAM and let c be a smooth curve passing through\\nm1, m2 ∈M. Define Bc(t)\\nT c = {c(t′) ∈Oc(t) : t′ ≥t}. An optical field\\nfrom m1 to m2 along c with m1, m2 /∈∂c is a map V : t 7→OM such that\\nV (t) := Vt ∈Oc(t) and Vt(c(t)) ∈Bc(t)\\nT c where by Vt(c(t)) we mean the point\\non the curve obtained by the action of Vt on c(t).\\n18\\nIn other words, an optical field along c is an assignment of a flow operator Vt\\nwith Vt an element of the OFM at c(t) such that such that the action Vt on c(t)\\nremains on the curve. Thus, the action of Vt on the base point c(t) at time t induces\\nmotion along the curve. When m1 and m2 are clear from the context, we simply\\nrefer to Vt as the optical field along c.\\nIn essence, the curve Vt traces a curve in OM as t varies with a consistent\\naction on c(t). By Bc(t)\\nT c we mean the intersection of the K-dimensional flow\\nneighborhood Bc(t) with the one dimensional curve c starting at c(t) and hence,\\nBc(t)\\nT c is a one dimensional embedded curve in Bc(t) i.e., Bc(t)\\nT c is a one\\ndimensional “slice” of Bc(t). We assume that Bc(t)\\nT c is connected.\\nTo measure the distance traveled by the action of Vt on c(t), we define a radius\\nrt restricted along the curve as opposed to the complete flow radius rc(t) at c(t)\\nrt =\\nsup\\nn∈Bc(t)\\nT c\\ndc(c(t), n),\\nwhere dc(·, ·) is the flow metric restricted to the curve c. Likewise, the curvature\\nKt along c is the ratio\\nKt = 1\\nrt\\n.\\nSince Bc(t)\\nT c is connected and 1D, the distance dc(c(t), m) between c(t) and\\nm ∈Bc(t)\\nT c characterizes m in the following sense. Given any positive constant\\n0 ≤η ≤rt there is a unique m ∈Bc(t)\\nT c with dc(c(t), m) = η. Thus, by\\nspecifying the distance along the curve c, we effectively characterize the curve.\\nLifting this observation into Oc(t), we have the following result.\\nTheorem 3.4. Let M be an IAM, let c be a curve passing through m1, m2 ∈M,\\nand let Vt be an optical field from m1 to m2 along c. Then, Vt is completely\\ncharacterized by the function hV (t) = dc(Vt(c(t)), c(t)) in the sense that for any\\nnon-negative function h(t) bounded pointwise by rt, there exists a unique optical\\noptical field Vt such that hV (t) = h(t).\\nProof. That 0 ≤hV (t) ≤rt is clear from the definitions above. Let h(t) be any\\nnon-negative function bounded by rt. Then, for fixed t = t0 we have that 0 ≤\\nh(t0) < rt0. By the remark made previously, we have a unique mt0 ∈Bc(t0)\\nT c\\nwith dc(c(t0), mt0) = h(t0). Now, as mt0 ∈Bc(t0)\\nT c, in particular, mt0 ∈Bc(t0)\\nand hence there exists a unique φt0 ∈Oc(t0) such that\\nφt0(c(t0)) = mt0.\\n19\\nAs t0 was arbitrary, as t varies, we can define Vt = φt. Moreover,\\nhV (t) = dc(Vt(c(t)), c(t)) = dc(φt(c(t)), c(t)) = dc(mt, c(t)) = h(t)\\nso that h(t) characterizes Vt.\\nRecall that we view an optical flow field Vt along c as a curve in OM. Theorem\\n10 states that this curve is characterized by the function hV (t) in the sense that for\\na given Vt along the (fixed) curve c, the function hV (t) contains all the information\\nabout the motion induced by Vt on the curve i.e., hV (t) measures the distance to\\nwhich Vt transports c(t) in Bc(t)\\nT c. Since this function is of prime importance,\\nwe make the following definition.\\nDefinition 3.5. Given an optical field Vt along a curve c, define its motion function\\nto be\\nhV (t) = dc(Vt(c(t)), c(t)).\\nNote that by continuity of the metric dc(·, ·) and c(t), the function hV (t) is also\\ncontinuous.\\n3.3. Parallel flow fields\\nThere is a very natural geometric interpretation of the motion function hV of\\nan optical flow field Vt along a curve c. Namely, it is a measure of the distance\\ntraveled along the curve at time t by c(t) when acted upon by Vt. Thus, it is natural\\nto think of instantaneous changes in hV in t as a measure of the velocity of the\\nmotion induced by Vt on c(t). In classical geometry, the class of constant velocity\\ncurves is especially important; they correspond to uniform motions. Similarly, we\\nwill be interested in the class of constant motion functions hV . These correspond\\nto optical fields Vt along c that induce uniform motion along c, where by uniform\\nmotion we mean the distance traveled along c is constant for all time.\\nAnother key link with classical differential geometry is the notion of parallel\\ntransport (or parallel translation) of tangent vectors [9]. Parallel transport is a key\\ntool for “moving” tangent vectors from different tangent spaces while preserving\\ndirection/orientation along the curve. Parallel transport utilizes the inherent linear\\nstructure of the tangent space to define a linear map between tangent on points\\nalong the curve. We aim to develop a similar analytic tool for IAMs. However,\\nan immediate stumbling block is the clear lack of linear structure in the OFM.\\nWe therefore take a different approach to defining parallel translation in the OFM\\ncase using motion functions.\\n20\\nTo motivate our definition, we recall that a vector field along a curve c on a\\nmanifold is parallel if its covariant derivative along c vanishes. The covariant\\nderivative is in essence a way of differentiating the vector field along c. The rela-\\ntion between parallel translation and parallel vector fields is that, given a tangent\\nvector v in the tangent space of a point c(t) on the curve c, it is possible to extend\\nv along c by parallel translation to yield a parallel vector field along c. In the OFM\\ncase, we have the motion function of an optical field along c at our disposal and\\nwe use it to characterized parallelism of the field along the curve.\\nDefinition 3.6. An optical field Vt along a curve c, is parallel if the derivative of\\nits motion function with respect to t is zero, or equivalently, if the motion function\\nis constant along c, i.e., hV (t) is a constant.\\nIn all that follows, we will denote by Ω(c, m1, m2) the space of all optical\\nfields through m1 and m2 along a curve c passing through m1, m2 ∈M. When\\nm1, m2 are understood from context, we simply refer to this space as Ω(c). The\\nsubclass of parallel fields along c will be denoted by ω(c).\\nA few facts are immediate from the above definition. First, since hV (t) ≤rt\\nfor all t, it is clear that if Vt is to be parallel along c, then hV (t) is a constant hV\\nindependent of t and hV ≤inft rt. Therefore, in the future, we will suppress the\\nargument t in the motion function hV (t) of a parallel flow field. Second, since Vt is\\ncharacterized by hV , we see that for any constant δ such that 0 ≤δ < inft rt, there\\nis a parallel optical field along c(t) such that hV = δ. Such a parallel optical field\\ncan be obtained, for example, by choosing for each t a flow operator φt ∈Oc(t)\\nwith dc(φt(c(t)), c(t)) = δ. The existence of such an optical field φt is guaranteed\\nby the above theorem. Given φ ∈Oc0 we aim to extend φ throughout the curve\\nto obtain a flow field Vt such that Vt is parallel along c with hV = dc(φ(c0), (c0)).\\nThe following result allows for such parallel translation of flow operators along a\\ncurve.\\nProposition 3.7. Let M be an IAM, and let c be a curve through m1, m2 ∈M.\\nLet ϵ = inft rt. Then, given any φ ∈Oc(t0) with δ = dc(φ(c(t0)), c(t0)) < ϵ there\\nexists a unique parallel optical field along c(t) with hV (t) = δ.\\nProof. As δ < ϵ, in particular δ < rt. Thus, invoking the previous theorem for the\\nspecial case of the constant function h(t) = δ, we have the existence of a unique\\noptical field Vt along c(t) such that hV (t) = δ. Moreover, since hV (t) is constant,\\nVt is parallel.\\n21\\nIn contrast with the classical case, parallel transport along a curve is dependent\\non the nature of the flow operator, i.e., an arbitrary flow operator φ ∈Oc0 cannot\\nbe parallel translated along c unless dc(φ(c0), c0) < inft rt. This constraint is\\nrelated to the nature of the curve; parallel transport along a curve that contains\\npoints with high curvature Kt is limited to those flow operators that induce smaller\\nmotion along the curve. Moreover, the possibility of parallel transport of φ ∈Oc(t)\\nhas a global dependence, i.e., it depends on the curvature of the entire curve, not\\nonly the curvature Kt at the point c(t).\\nThus, we are naturally led to study those curves for which parallel translation\\nof an operator φ at a single point c(t0) ensures the existence of parallel translation\\nof operators at any other point on the curve. Clearly, the necessary condition is\\nthe invariance of Kt with t, and therefore we are led to consider curves for which\\nthe curvature Kt is independent of t, i.e., a constant. This special class of curves\\nhas a very rich structure that we explore in the following sections.\\n3.4. Approximation of arbitrary flow fields by parallel flow fields\\nIn this section, we consider the problem of approximating an arbitrary Vt ∈\\nΩ(c) by elements in ω(c). Consider an optical field Vt ∈Ω(c) (not necessarily\\nparallel) along a curve c of constant flow curvature. A natural question to ask\\nis how far away Vt is from being parallel. One way to do this is to seek the\\n“best” approximation of Vt by a parallel field Wt ∈ω(c) along c. To quantify the\\napproximation, we consider the following cost\\ne(t) = dc(Vt(c(t)), Wt(c(t))).\\nIn words, e(t) is a measure of how the action of Vt on c(t) differs from the action\\nof Wt on c(t). Note that e(t) is bounded above by hV (t) + hW since e(t) =\\ndc(Vt(c(t)), Wt(c(t))) ≤dc(Vt(c(t)), c(t)) + dc(c(t), Wt(c(t))) = hV (t) + hW.\\nWhile e(t) is a pointwise error, we will need to consider the total error over\\nthe entire curve. To this end, a natural choice of error metric is\\nE(V, W) =\\nZ b\\na\\ne(t)dt,\\nwhere the domain of c is the interval (a, b). Thus, our goal is to find a parallel\\noptical field Wt ∈ω(c) that minimizes E(V, W), i.e.,\\nW ∗= arg min\\nW E(V, W).\\n22\\nIn general, a minimizer may not exist, or it may not be unique if one exists. How-\\never, the greatest issue is the strong dependence of the error e(t) on the flow\\nmetric, which prevents a generic solution to the minimization problem since we\\ncannot infer the convexity of the problem as stated. We can, however, obtain a\\nuniversal lower bound on the error independent of the flow metric as follows\\n|hV (t) −hW| = |dc(Vt(c(t)), c(t)) −dc(W(c(t)), c(t))| ≤e(t).\\nTherefore, we seek a minimizer of\\nZ b\\na\\n|hV (t) −hW|dt. Note that since Wt is\\nparallel, hW is a constant, say h ≥0. Moreover, since c is a path of constant\\nflow curvature, rt is a constant r > 0. Since h characterizes Wt, a minimizer h∗\\nyields a lower bound for E(V, W). Our goal then, is to find an optimal constant\\nh∗that minimizes ]\\nE(h) =\\nZ b\\na\\n|hV (t) −h|dt. We claim that a solution h∗is a\\ncertain “median” of hV (t). We first define Ak = {t ∈(a, b) : hV (t) > k} and\\nBk = {t ∈(a, b) : hV (t) ≤k} for some k. We claim that an optimal constant ˆh\\nis such that λ(Aˆh) = λ(Bˆh), where λ(S) denotes the measure of a set S.\\nTheorem 3.8. Let bh be the constant such that λ(Abh) = λ(Bbh). Then, bh minimizes\\n]\\nE(h).\\nProof. Note that the function ]\\nE(h) is convex in h with h ∈(a, b) and (a, b) a\\nconvex interval. Therefore, we are guaranteed a minimizer h∗. Now, without loss\\nof generality, we assume that h∗< bh. We evaluate the cost over the two regions\\nAbh and Bbh\\n^\\nE(h∗) =\\nZ b\\na\\n|hV (t) −h∗|dt =\\nZ\\nAbh\\n|hV (t) −h∗|dt +\\nZ\\nBbh\\n|hV (t) −h∗|dt.\\nDefine B1 = {t : h∗< hV (t) < ˆh} and B2 = {t : hV (t) < h∗} and note that\\nλ(Abh) −λ(B1) −λ(B2) = 0. We can now express ^\\nE(h∗) in terms of ]\\nE(bh) as\\n^\\nE(h∗) = g\\nEAbh(bh) + (bh −h∗)λ(Abh) + g\\nEBbh(bh) −(bh −h∗)λ(B2) −α,\\nwhere f\\nEX(bh) denotes the cost function restricted to the subset X ⊆(a, b) and α\\nis a positive constant that measures the difference of bh −h∗on the set B1. The\\nmaximum value of α is (bh −h∗)λ(B1) and hence\\n^\\nE(h∗) ≤g\\nEAbh(bh) + (bh −h∗)(λ(Abh) −λ(B1) −λ(B2)) + g\\nEBbh(bh).\\n23\\nSince λ(Abh) −λ(B1) −λ(B2) = 0, we conclude that\\n^\\nE(h∗) ≤]\\nE(bh)\\nand hence h∗= bh. The case of h∗> bh follows from symmetry.\\nWe illustrate the approximation of non-parallel flow fields by parallel flow\\nfields with the example of video resampling where we can consider a video I to be\\na curve on an IAM i.e., a video I = {It, 0 ≤t ≤T} with T > 0. This application\\nis related to the problem of dynamic time warping (DTW) [26, 27, 28], where\\none is interested in measuring the similarity between two sequences that vary in\\ntime or speed. As we shall see, this can be used for matching or aligning video\\nsequences with a warped time axis [27, 28].\\nConsider the IAM generated by imaging a black disk on an infinite white\\nbackground starting with an initial velocity v0 and accelerating with constant ac-\\nceleration a along a fixed direction. For instance, the disk can be thought of as\\nundergoing freefall off an infinitely high cliff. The IAM is a 1D curve c and\\nhomeomorphic to R+, the non-negative reals. Note that the curvature is every-\\nwhere zero since rt = ∞. Given an arbitrary flow field Vt along c, our goal is\\nto analytically construct a parallel field ˜Vt such that ˜Vt is the unique parallel flow\\nfield that minimizes ]\\nE(h). We first consider the video obtained by the action of Vt\\ni.e. I = {Vt(c(t))}. Since Vt is not parallel, the video will show the disk moving\\nwith non-uniform motion. Our goal is to make the video uniform, i.e., generate a\\nnew video ˜I from ˜Vt that shows the disk moving with uniform motion.\\nFrom the physics of the problem, it is clear that dc(c(t), c(t + δt)) = K(vtδt +\\n1\\n2aδ2\\nt ) for some positive constant K and any time increment δt with vt being the\\nvelocity at time t. Now, since ˜Vt is to be a parallel flow field, we have that h ˜V is\\na constant denoted by h. Thus, dc(˜Vt(c(t)), c(t)) = dc(c(t), c(t + δt)) = h so that\\nK(vtδt + 1\\n2aδ2\\nt ) = h. Rearranging this equation, we arrive at\\nδ2\\nt + 2vt\\na δt −2h\\naK = 0.\\nSolving for δt, we obtain two real roots δ1,2\\nt\\n= −vt\\na ±\\nq\\n(vt\\na )2 + 2h\\naK of which the\\n(physically meaningful) positive root δ1\\nt = −vt\\na +\\nq\\n(vt\\na )2 + 2h\\naK > 0 is retained.\\nThus, by defining ˜Vt such that ˜Vt(c(t)) = c(t + δ1\\nt ), we see that ˜Vt is the unique\\nparallel flow field that minimizes ]\\nE(h). The new video ˜I = {˜Vt(c(t))} will\\nthus show the disk moving with constant velocity. With this, we have effectively\\nlinearized the motion and made it independent of the acceleration of the disk.\\n24\\n4. Multiscale Structure of Parallel Flow Fields\\nAs indicated in the Section 3, the set of parallel optical fields is a very special\\nsubset of the set of all optical fields along a fixed curve c. In this section, we\\nwill construct a monoid structure (i.e., a set with an associative operation and\\nidentity) on the set of all optical fields along a fixed curve c and show that the\\nclass of parallel fields forms a submonoid of this set under some conditions on\\nthe curvature along the curve. Moreover, the monoid operation yields a multiscale\\nstructure on the set of parallel optical fields.\\n4.1. Monoid structure on Ω(c)\\nAs noted previously in Section 2, a clear disadvantage in dealing with the\\nspace of all optical fields along a curve is the lack of a linear, or more generally,\\nany algebraic structure. In order to remedy this situation, we will define a binary\\noperation on the set of optical fields that yields a monoid structure. We first fix a\\ncurve c passing through m1, m2 ∈M.\\nRecall that a generic Vt ∈Ω(c) is characterized by its motion function hV (t).\\nThus, operations defined on motion functions hV (t) translate to operations on\\nVt ∈Ω(c). With this in mind, we define for Vt, Wt ∈Ω(c) the sum Vt + Wt to be\\nthe unique optical field with motion function\\nhV +W(t) = min(hV (t) + hW(t), rt).\\nSince hV +W(t) ≤rt for all t, we see that hV +W(t) corresponds to a unique flow\\nfield that we define to be Vt + Wt. This operation is clearly commutative. Note\\nalso that the trivial (parallel) field Zt defined to be the field that acts trivially on\\nc(t); i.e.,\\nZt(c(t)) = c(t)\\nis characterized by the motion function hZ(t)\\n=\\n0 since hZ(t)\\n=\\ndc(Zt(c(t), c(t)) = dc(c(t), c(t)) = 0. Moreover, for any Vt ∈Ω(c), we have\\nthat\\nZt + Vt = Vt.\\nWe see that Zt acts as the identity element in Ω(c). In addition to this, there is also\\nthe unique optical field Ut characterized by\\nhU(t) = rt\\nthat satisfies\\nVt + Ut = Ut\\n25\\nfor all Vt ∈Ω(c) and hence acts as the “absorbing” element of Ω(c).\\nClearly, we do not have “inverses” with respect to “+” in the sense that, given\\na generic Vt ∈Ω(c), there does not exist a Wt such that Vt + Wt = Zt. However,\\nwe do have “conjugates” with respect to “+” in the following sense. Given any\\nVt ∈Ω(c), there is a unique V ∗\\nt ∈Ω(c) such that\\nVt + V ∗\\nt = Ut.\\nV ∗\\nt is defined by its motion function\\nhV ∗(t) = rt −hV (t).\\nWe refer to V ∗\\nt as the conjugate of Vt. Moreover,\\n(V ∗\\nt )∗= Vt.\\nFinally, we note that Ut and Zt are conjugates.\\nProposition 4.1. Ω(c) is a monoid under the operation “+” defined in (22).\\nProof. We only verify associativity, since Zt provides the identity.\\nGiven\\nVt, Xt, Yt ∈Ω(c), we consider the sums (Vt + Xt) + Yt and Vt + (Xt + Yt).\\nIf hV (t), hX(t), hY (t) are such that hV (t) + hX(t) + hY (t) < rt then both sides\\nare clearly equal. If on the other hand, hV (t) + hX(t) + hY (t) ≥rt then we must\\nhave that either the sum hV (t)+hX(t)+hY (t) taken two factors at a time exceeds\\nrt or that the combined sum of all three factors exceeds rt with the sum of no two\\nfactors exceeding rt. In the first case, we assume that hV (t) + hX(t) ≥rt, which\\nimplies the sum\\n(Vt + Xt) + Yt = Ut\\nwith (Xt + Yt) ̸= Ut, i.e.,\\nhX(t) + hY (t) < rt.\\nHowever, Vt + (Xt + Yt) is characterized by\\nmin(hV (t) + min(hX(t) + hY (t), rt), rt) = min(hV (t) + hX(t) + hY (t), rt) = rt\\nwhich shows that\\nVt + (Xt + Yt) = Ut\\nas well. The other cases follow by similar arguments.\\n26\\n4.2. Parallel fields along curves of constant curvature\\nThe addition operation defined above restricts to the set ω(c) of parallel fields\\nalong c(t). However, for generic c(t), the sum Vt + Wt of two parallel fields\\nVt, Wt ∈ω(c) may result in a possibly non-parallel field. For instance, consider\\nhV (t), hW(t) such that hV (t0) + hW(t0) < rt0 but hV (t1) + hW(t1) ≥rt1 for\\nsome t0, t1. Clearly, the sum is not parallel since in the first case, hV +W(t0) =\\nhV (t0) + hW(t0) < rt0 while hV +W(t1) = rt1 so that hV +W(t) is not constant.\\nHowever, that if rt is constant along c, i.e., the flow radius is constant along\\nthe path, then the above situation is vacuous. Since Kt = 1\\nrt is the curvature along\\nthe curve c, we are essentially requiring the curvature to be constant along c. We\\nformally record the above observation.\\nProposition 4.2. Let c be a curve with constant curvature Kt. Then, the operation\\n“+” restricted to ω(c) is well defined and ω(c) is a submonoid of Ω(c).\\nProof. We need only verify closure of “+” in ω(c) since Zt ∈ω(c). If Vt ∈ω(c),\\nthen hV (t) is a constant and we will therefore suppress the argument t in hV (t).\\nNote that since c is of constant curvature, rt is a constant r > 0. Thus, if Vt, Wt ∈\\nω(c), then hV +W = min(hV + hW, r). If hV + hW < r then as hV and hW are\\nboth constant so is their sum hV + hW and\\nhV +W = hV + hW.\\nIf hV + hW ≥r, then\\nhV +W = min(hV + hW, r) = r.\\nIn either case, hV +W is constant and hence\\nVt + Wt ∈ω(c).\\nThus, curves c that have constant curvature at all points are very special; not\\nonly is parallel transport determined by a single point on the curve, but ω(c) is\\nalso a submonoid of Ω(c).\\n27\\n4.3. Multiscale structure of ω(c)\\nIn this section, we look for finite submonoids of ω(c). We would like the\\nsubmonoids to be canonically defined, by which we mean that they depend only\\non the geometry of the constant curvature curve c. In particular, we construct for\\neach positive integer k, a collection of finite submonoids Vn,k of ω(c) with n a\\nnon-negative integer and c a constant curvature path. Moreover, we will see that\\nthis collection is naturally nested, i.e.,\\nV0,k ⊂V1,k ⊂· · ·\\nIn essence, this provides a multi-scale view of ω(c).\\nSince ω(c) consists of parallel optical fields, we will simply denote the motion\\nfunction hV (t) of Vt ∈ω(c) as hV . Moreover, we will suppress the subscript t\\nwhen referring to elements of Vt ∈ω(c). Also, for V ∈ω(c), we mean by V\\nk the\\nelement in ω(c) with motion function being the constant hV\\nk . Recall also that ω(c)\\npossesses two canonical elements Z, U ∈ω(c) ∩Ω(c) that act as the trivial and\\nabsorbing elements of ω(c) respectively.\\nWe begin now with the construction of Vn,k. Fix a positive integer k and set\\nV0,k = {Z, U}.\\nNext, we inductively set\\nVn,k =\\nn\\nZ, U\\nkn, 2U\\nkn , ...(kn−1)U\\nkn\\n, U\\no\\n.\\nNow, it is clear that\\nV0,k ⊂V1,k ⊂....\\nMoreover, by the constant curvature condition, the sum of any two elements in\\nVn,k remains in Vn,k while associativity is obtained from the corresponding prop-\\nerty in ω(c). Finally, since Z ∈Vn,k for all n, k, we conclude that each Vn,k is a\\nfinite submonoid of ω(c).\\nWe have thus obtained a sequence of finite submonoids of ω(c). Moreover,\\nwith increasing n, it is clear that an arbitrary V ∈ω(c) can be uniformly approx-\\nimated by eV ∈Vn,k in the sense that |hV −heV | can be made arbitrarily small by\\nchoosing larger n. In other words, the sequence Vn,k is “dense” in ω(c). Finally,\\nsince the basic generators of Vn,k are Z, U ∈ω(c) ∩Ω(c), this construction is\\ncanonical in the sense that it depends only on the set of {Z, U}, which are in turn\\nare characterized by the global geometry of the curve c.\\n28\\nIn Section 3, we saw that with curvature conditions on a curve c, it is possible\\nto approximate an arbitrary flow field by a parallel one. The results presented\\nabove show that one can further approximate a parallel flow field with a finite\\ncollection of “template” elements from ω(c). This is very much similar to the\\nmultiscale representation that wavelets provide for natural images. Indeed, the\\nmultiscale structure inherent to monoids paves the way for “lossy compression”\\nof arbitrary flow fields by storing only the relevant scales Vn,k. In addition to\\ncompression, the multiscale structure can potentially enable fast computations on\\nthe flow fields. Operations on the flow fields can equivalently be mapped to those\\non the Vn,k without loss in accuracy while gaining significantly in the number of\\ncomputations required.\\n5. Discussion\\nIn this paper, we have developed the mathematical foundations of optical flow-\\nbased transport operators for image manifolds, which were introduced empirically\\n[13]. Our main theoretical contribution was the development of the flow metric\\nfor using the ambient metric on the OFMs. Using the flow metric, we derived dif-\\nferential geometric analogues of tangent bundles, vector fields, parallel transport,\\ncurvature etc. When the IAM is generated by Lie group parameters, we showed\\nthat the OFM framework includes previous algebraic methods as a special case.\\nMoreover, since the flow neighborhood at each point is the entire IAM, we can\\nobtain geodesics between any two images using flow operators. While this paper\\nhas focused on explaining and extending the results obtained in [13], we envision\\nthat the theory could make an on a large class of applications involving image\\nmanifolds.\\nA clear assumption in our analysis has been that optical flow is the transport\\noperator of choice for IAMs. While this is true for a majority of IAMs gen-\\nerated by motion-induced parameter changes such as translations, rotations and\\nunstructured plastic deformations, there are classes of IAMs for which the choice\\nof transport operator is not immediately clear. For instance, for illumination man-\\nifolds obtained by variations in the illumination of an object, optical flow may not\\nbe the transport operator of choice, since such manifolds do not in general obey\\nthe brightness constancy requirement needed in optical flow computations. More-\\nover, in cases where there is significant self-occlusion during the imaging process,\\noptical flow may not be a practical transport operator. However, by regularizing\\nthe optical flow computation to handle occlusions by removing flow operators\\nthat lead to undefined motion between pixels, one can partially circumvent this\\n29\\nissue, and the methods of this paper can be profitably applied. However, these\\nare aspects of a more computational nature, and we reserve them for an alternate\\nforum.\\nA number of avenues for future work exist.\\nFirst, our work hints that it\\nshould be possible to develop additional geometric tools such as affine connec-\\ntions, holonomy, etc. using flow operators. These will complete the IAM anal-\\nysis toolbox. Second, although our development has been specific to the case\\nof IAMs with optical flow, the basic model is extensible to a wide variety of\\nsignal ensembles with appropriately defined transport operators. For instance,\\na manifold model for speech signals has been proposed in [29] where appropriate\\ntransport operators and the analog of OFMs may involve a frequency domain ap-\\nproach. Once the “right” transport operator has been identified for the application\\nin hand, one can conceivably define and study metrics similar to our flow metric\\nand thereby develop analytic tools for further analysis.\\nAcknowledgments\\nThe authors thank Chinmay Hegde for valuable discussions and insightful\\ncomments on the manuscript.\\nThis work was partially supported by the grants NSF CCF-0431150,\\nCCF-0728867, CCF-0926127, CCF-1117939, ARO MURI W911NF-09-1-0383,\\nW911NF-07-1-0185, DARPA N66001-11-1-4090, N66001-11-C-4092, N66001-\\n08-1-2065, AFOSR FA9550-09-1-0432, and LLNL B593154.\\nAppendix A. Smoothness and Distance Properties of OFMs\\nIn this appendix, we establish the smoothness and isometry properties of\\nOFMs associated with two interesting classes of IAMs: the affine articulation\\nmanifold and the pose manifold.\\nAppendix A.1. Affine articulation manifold\\nAffine articulations are parameterized by a 6-dimensional articulation space\\nΘ = R6; each articulation θ can be written as θ = (A, t), with A ∈R2×2 and\\nt ∈R2. Any image belonging to the IAM can thus be written as\\nI1(x) = Iref ((A + I)x + t) ,\\n(A.1)\\n30\\nwhere x = (x, y) is defined over the domain X = [0, 1] × [0, 1] and where Iref is a\\nreference image.2 The optical flow field fθ associated with the transport operator\\ncan be written as fθ(x) = fA,t(x) = Ax + t. Now, recall that the OFM at Iref is\\ndefined as\\nOIref = {fθ :\\nθ = (A, t), A ∈R2×2, t ∈R2}.\\nThe linear dependence of the optical flow field on both A and t implies that the\\nOFM, which is the collection of optical flows at Iref, is infinitely smooth. Finally,\\nnoting that the OFM is independent of the reference image, we can establish the\\nfollowing result.\\nLemma 1. For affine articulations, the OFM at any reference image is infinitely\\nsmooth.\\nNext, we consider distances between optical flows and establish that the OFM\\nis isometric.\\nLemma 2. For affine articulations, the OFM at any reference image is globally\\nisometric.\\nProof. Given two articulations θ1 = (A1, t1) and θ2 = (A2, t2), the Euclidean\\ndistance between them is given by\\n(d(fθ1, fθ2))2\\n=\\nZ\\nx∈X\\n∥fθ1(x) −fθ2(x)∥2\\n2 dx\\n=\\nZ\\nx∈X\\n∥(A1 −A2)x + (t1 −t2)∥2\\n2 dx\\n=\\n(θ1 −θ2)TΣ(θ1 −θ2),\\nwhere\\nΣ =\\nZ\\nx∈X\\n\\x12\\x14 x\\n1\\n\\x15 \\x02\\nxT 1\\n\\x03\\x13\\ndx.\\nFor X = [0, 1] × [0, 1], it is easily shown that Σ is full-rank and positive definite.\\nHence, we have\\nd(fθ1, fθ2) = ∥θ1 −θ2∥Σ,\\nwhere ∥·∥Σ is the Mahalanobis (or weighted Euclidean) distance defined using the\\nmatrix Σ. This implies that the OFM is Euclidean and, hence, globally isometric.\\n2Boundary-related issues are always an concern when we define images over a finite domain.\\nHere, we circumvent this by assuming that the regions of interest are surrounded by a field of\\nzeros. This allows us to assign undefined values to zero and satisfy (A.1)\\n31\\nAppendix A.2. Pose manifold\\nThe pose manifold is the IAM corresponding to the motion of a camera observ-\\ning a static scene. It is well-known that the articulation space is 6-dimensional,\\nwith 3 degrees of rotation and 3 degrees of translation of the camera, i.e.,\\nΘ = SO(3) × R3. We assume that the optical flow is the (unique) 2-dimensional\\nprojection of the motion flow of the scene induced due to the motion of the cam-\\nera.\\nWithout loss of generality, we assume the reference articulation θref\\n=\\n(R0, t0) = (I, 0) and that the camera’s internal calibration is known and accounted\\nfor [30]. At the reference articulation θref, let the depth at a pixel x be given by\\nλref(x). Under an articulation θ = (Rθ, tθ), the optical flow observed at the pixel\\nx is given by\\nf(θ)(x) = P\\n\\x12\\nλref(x)Rθ\\n\\x14 x\\n1\\n\\x15\\n+ t\\n\\x13\\n−P\\n\\x12\\nλref(x)\\n\\x14 x\\n1\\n\\x15\\x13\\n(A.2)\\nwhere P(·) is a projection operator such that P(x, y, z) = (x/z, y/z). Note that\\nP is a well-defined and infinitely smooth function provided z ̸= 0.\\nThe OFM O is the image of the map f(θ) = {f(θ)(x) :\\nx ∈X}, where X\\nis the image plane. We now establish the smoothness of the OFM.\\nLemma 3. Consider the OFM corresponding to a pose manifold of a scene with\\ndepth map (at the reference articulation θref) strictly bounded away from zero, i.e,\\n∀x, λref(x) > λ > 0. Then there exists a neighborhood of θref where f(θ) =\\n{f(θ)(x); x ∈X} is an infinitely smooth map.\\nProof. The smoothness of f(θ) follows from the smoothness of f(θ)(x), which\\nin turn follows from the smoothness of the projection operator P.\\nNote that\\nP(x, y, z) = (x/z, y/z) is well defined and infinitely smooth only if z ̸= 0.\\nWhen all points in the scene have depth bounded away from zero, then there is\\nguaranteed a neighborhood of Θ around θref wherein all points continue to have\\ndepth bounded away from zero. This ensures that the projection of all points is\\nwell defined, and hence, f(θ) is infinitely smooth in this neighborhood.\\nNote that, in contrast to affine articulations, where the corresponding OFM is\\nsmooth globally, the OFM associated with the pose manifold is smooth only over\\na neighborhood of the reference point.\\nNext, we consider distances between optical flows and establish that the OFM\\nis locally isometric. We begin by defining the following representation for rotation\\n32\\nmatrices. Let ω = (ωx, ωy, ωz) ∈R3, and let Ωω ∈R3×3 be the skew-symmetric\\nmatrix defined as\\nΩω =\\n\\uf8ee\\n\\uf8f0\\n0\\n−ωx\\nωy\\nωx\\n0\\n−ωz\\n−ωy\\nωz\\n0\\n\\uf8f9\\n\\uf8fb.\\nNoting that the matrix exponential eΩω is a rotation matrix, we define our articu-\\nlations as θ = (ω, t) ∈R6, with t = (tx, ty, tz).\\nBefore we state a formal result, we need to introduce two assumptions that\\nwill help in simplifying the derivation. First, we assume that the imaging model\\nis well-approximated by a weak perspective model [30]. In the weak perspective\\nmodel, it is assumed that the variations in the scene depth are significantly smaller\\nthan the average depth of the scene. In such a case, the projection map P(x) =\\n(x/z, y/z) can be well-approximated by\\nPwp(x) = (x/zav, y/zav),\\nwhere zav is the average scene depth. As a consequence, translations along the z-\\naxis are unobservable [30]; hence, we restrict the articulation space to the rotation\\nof the camera and translation along x and y axes alone. Second, we assume that\\nthe rotation undergone by the camera is small. This enables us to approximate the\\nmatrix-exponential eΩω ≈I + Ωω. As a consequence of this assumption, we only\\nobtain a local isometry result. With these two assumptions, we are ready to state\\na result on the distances between optical flows.\\nLemma 4. Consider the pose manifold under the assumption of the weak per-\\nspective imaging model. Then the OFM is locally isometric.\\nProof. Without loss of generality, we denote our reference articulation as θref = 0,\\nwhich corresponds to identity rotation matrix and null translation vector. We are\\ninterested in the distance between two optical flow fields f(θ1) and f(θ2). Under\\nour assumptions of weak perspective imaging model and small rotation, we can\\ncompute the distance between the optical flows to be\\nf(θ1)(x) −f(θ2)(x)\\n=\\nPwp\\n\\x12\\nλrefR1\\n\\x14 x\\n1\\n\\x15\\n+ t1\\n\\x13\\n−Pwp\\n\\x12\\nλrefR2\\n\\x14 x\\n1\\n\\x15\\n+ t2\\n\\x13\\n=\\n1\\nzav\\n\\x14 (−λref(ω1,xy −ω1,y) + t1,x) −(−λref(ω2,xy −ω2,y) + t1,x)\\n(λref(ω1,xx −ω1,z) + t1,y) −(λref(ω2,xx −ω2,z) + t2,y)\\n\\x15\\n=\\n1\\nzav\\n\\x14 −λref(ω1,x −ω2,x)y + λref(ω1,y −ω2,y) + (t1,x −t2,x)\\nλref(ω1,x −ω2,x)x −λref(ω1,z −ω2,z) + (t1,y −t2,y)\\n\\x15\\n33\\nNotice that both t1,z and t2,z are absent in the expression above. As noted above,\\nthis is due to the assumption of weak perspective imaging model which makes the\\ntranslation of the camera along the z-axis unobservable. A key observation is that\\nthe articulation parameters θ1 = (ω1, t1) and θ2 = (ω2, t2) can be expressed as a\\nfunction that is linear in the expression above. Hence,\\nf(θ1)(x) −f(θ2)(x) = A(x)\\n\\x14 ω1 −ω2\\nt1 −t2\\n\\x15\\n.\\nFinally, summing over x ∈X, we obtain\\nd(f(θ1), f(θ2))2 = (θ1 −θ2)T\\n\\x12Z\\nx∈X\\nAT(x)A(x)dx\\n\\x13\\n(θ1 −θ2).\\nHence, the OFM is locally isometric.\\nReferences\\n[1] D. L. Donoho, C. C. Grimes, Image manifolds which are isometric to eu-\\nclidean space, J. of Math. Imaging and Vision 23 (2005) 5–24.\\n[2] M. B. Wakin, D. L. Donoho, H. Choi, R. G. Baraniuk, The multiscale struc-\\nture of non-differentiable image manifolds, in: Proc. SPIE Wavelets XI,\\n2005.\\n[3] R. R. Coifman, S. Lafon, A. B. Lee, M. Maggioni, F. Warner, S. Zucker,\\nGeometric diffusions as a tool for harmonic analysis and structure definition\\nof data: Diffusion maps 102 (21) (2005) 7426–7431.\\n[4] B. J. Culpepper, B. A. Olshausen, Learning transport operators for image\\nmanifolds, in: Adv. in Neural Info. Proc. Sys., 2009.\\n[5] J. Tenenbaum, V. de Silva, J. Landford, A global geometric framework for\\nnonlinear dimensionality reduction, Science 290 (5500) (2000) 2319–2323.\\n[6] S. Roweis, L. Saul, Nonlinear dimensionality reduction by locally linear em-\\nbedding, Science 290 (5500) (2000) 2323–2326.\\n[7] M. Belkin, P. Niyogi, Laplacian eigenmaps and spectral techniques for em-\\nbedding and clustering, in: Adv. in Neural Info. Proc. Sys., 2001.\\n34\\n[8] Y. Ma, S. Soatto, J. Kosecka, S. Sastry, An Invitation to 3-D Vision: From\\nImages to Geometric Models, Springer-Verlag, 2005.\\n[9] M. P. do Carmo, Riemannian Geometry, Birkh¨auser, 1992.\\n[10] X. Miao, R. P. N. Rao, Learning the lie groups of visual invariance, Neural\\ncomputation 19 (10) (2007) 2665–2693.\\n[11] D. Lin, E. Grimson, J. Fisher, Learning visual flows: a lie algebraic ap-\\nproach, 2009.\\n[12] O. Tuzel, F. Porikli, P. Meer, Learning on lie groups for invariant detection\\nand tracking, in: IEEE Conf. Comp. Vision and Patt. Recog., 2008.\\n[13] A. C. Sankaranarayanan, C. Hegde, S. Nagaraj, R. G. Baraniuk, Go with the\\nflow: Optical flow-based transport for image manifolds, in: Allerton Conf.\\non Comm., Control and Computing, 2011.\\n[14] R. Li, R. Chellappa, Aligning spatio-temporal signals on a special manifold,\\nin: Euro. Conf. on Comp. Vision, 2010.\\n[15] M. I. Miller, L. Younes, Group actions, homeomorphisms, and matching: a\\ngeneral framework, Intl. J. of Comp. Vision 41 (1–2) (2001) 61–84.\\n[16] B. K. P. Horn, B. G. Schunck, Determining optical flow, Artificial intelli-\\ngence 17 (1-3) (1981) 185–203.\\n[17] D. Sun, S. Roth, M. J. Black, Secrets of optical flow estimation and their\\nprinciples, in: IEEE Conf. Comp. Vision and Patt. Recog., 2010.\\n[18] T. Brox, J. Malik, Large displacement optical flow: descriptor matching in\\nvariational motion estimation, IEEE Trans. Pattern Anal. Mach. Intell. 33 (3)\\n(2011) 500–513.\\n[19] H. Karcher, Riemannian center of mass and mollifier smoothing, Comm. on\\nPure and Appl. Math. 30 (5) (1977) 509–541.\\n[20] T. F. Cootes, C. J. Taylor, D. H. Cooper, J. Graham, Active shape models-\\ntheir training and application, Comp. vision and image understanding 61 (1)\\n(1995) 38–59.\\n35\\n[21] T. F. Cootes, G. J. Edwards, C. J. Taylor, Active appearance models, IEEE\\nTrans. Pattern Anal. Mach. Intell. 23 (6) (2001) 681–685.\\n[22] J. Kaplan, D. Donoho, The morphlet transform: A multiscale representation\\nfor diffeomorphisms, in: Workshop on Image Registration in Deformable\\nEnvironments, 2006.\\n[23] D. Beymer, T. Poggio, Image representations for visual learning, Science\\n272 (5270) (1996) 1905–1909.\\n[24] N. Jojic, B. J. Frey, Learning flexible sprites in video layers, in: IEEE Conf.\\nComp. Vision and Patt. Recog., 2001.\\n[25] S. A. Nene, S. K. Nayar, H. Murase, Columbia object image library (COIL-\\n100), T.R. No. CUCS-006-96, Dept. Comp. Science, Columbia University.\\n[26] M. E. Munich, P. Perona, Continuous dynamic time warping for translation-\\ninvariant curve alignment with applications to signature verification, in: Intl.\\nConf. on Comp. Vision, 1999.\\n[27] K. Wang, T. Gasser, Alignment of curves by dynamic time warping, Annals\\nof Statistics 25 (3) (1997) 1251–1276.\\n[28] A. Bosco, A. Bruna, S. Battiato, G. Puglisi, Digital video stabilization\\nthrough curve warping techniques, IEEE Trans. on Consumer Electronics\\n54 (2) (2008) 220–224.\\n[29] A. Jansen, P. Niyogi, Intrinsic fourier analysis on the manifold of speech\\nsounds, in: ICASSP, 2006.\\n[30] R. Hartley, A. Zisserman, Multiple view geometry, Cambridge university\\npress, 2000.\\n36\\n')]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 3 + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, "source": "", - "id": "84872aedbe970456" + "id": "84872aedbe970456", + "outputs": [], + "execution_count": null }, { "metadata": {}, @@ -1233,8 +599,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2025-04-30T09:44:01.940985Z", - "start_time": "2025-04-30T09:43:58.712696Z" + "end_time": "2025-04-30T10:41:49.649526Z", + "start_time": "2025-04-30T10:41:47.338329Z" } }, "cell_type": "code", @@ -1251,13 +617,13 @@ ], "id": "106b84a960377aad", "outputs": [], - "execution_count": 4 + "execution_count": 1 }, { "metadata": { "ExecuteTime": { - "end_time": "2025-04-30T09:46:23.580205Z", - "start_time": "2025-04-30T09:45:52.434420Z" + "end_time": "2025-04-30T10:41:56.657308Z", + "start_time": "2025-04-30T10:41:49.991801Z" } }, "cell_type": "code", @@ -1273,110 +639,183 @@ "\n", "The plan is: 1. Search the web for \"Friedrich Merz birthday\".\n", "2. Extract the date from the search results.\n", - "3. Provide the extracted date as the answer.\n", + "3. Provide the date as the answer.\n", "\n", "-------------------- Agent has been called -----------------------------------\n", - "\n", - "Agent has made a decision:\n", - " [{'name': 'web_search', 'args': {'query': 'Friedrich Merz birthday'}, 'id': '5105ab7c-041e-4cef-b3c4-256092d9cc5c', 'type': 'tool_call'}]\n", - "Waiting for 4 seconds...\n", - "\n", - "-------------------- Decision of forwarding has been made --------------------\n", - "\n", - "This is round: 2\n", - "The last message is: content='' additional_kwargs={'function_call': {'name': 'web_search', 'arguments': '{\"query\": \"Friedrich Merz birthday\"}'}} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-3b477f1f-5d26-4a58-ae29-581bd4ffcd4e-0' tool_calls=[{'name': 'web_search', 'args': {'query': 'Friedrich Merz birthday'}, 'id': '5105ab7c-041e-4cef-b3c4-256092d9cc5c', 'type': 'tool_call'}] usage_metadata={'input_tokens': 493, 'output_tokens': 7, 'total_tokens': 500, 'input_token_details': {'cache_read': 0}}\n", - "\n", - "-------------------- Agent has been called -----------------------------------\n", - "\n", - "Agent has made a decision:\n", - " I am sorry, I cannot fulfill this request. There was an error when calling the web_search tool. Please try again. []\n", - "Waiting for 4 seconds...\n", - "\n", - "-------------------- Decision of forwarding has been made --------------------\n", - "\n", - "This is round: 3\n", - "The last message is: content='I am sorry, I cannot fulfill this request. There was an error when calling the web_search tool. Please try again.' additional_kwargs={} response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []} id='run-70f8b036-ea1d-42e9-8d4b-f647ea13b31d-0' usage_metadata={'input_tokens': 540, 'output_tokens': 27, 'total_tokens': 567, 'input_token_details': {'cache_read': 0}}\n", - "The final answer is: February 11, 1955\n" + "\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001B[31m---------------------------------------------------------------------------\u001B[39m", + "\u001B[31mKeyboardInterrupt\u001B[39m Traceback (most recent call last)", + "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[2]\u001B[39m\u001B[32m, line 1\u001B[39m\n\u001B[32m----> \u001B[39m\u001B[32m1\u001B[39m \u001B[43mgraph\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\u001B[43m{\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mmessages\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[43m[\u001B[49m\u001B[43mHumanMessage\u001B[49m\u001B[43m(\u001B[49m\u001B[43mcontent\u001B[49m\u001B[43m=\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mSearch the web for the brith day of Friedrich Merz\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m]\u001B[49m\u001B[43m}\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langgraph\\pregel\\__init__.py:2795\u001B[39m, in \u001B[36mPregel.invoke\u001B[39m\u001B[34m(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, checkpoint_during, debug, **kwargs)\u001B[39m\n\u001B[32m 2793\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 2794\u001B[39m chunks = []\n\u001B[32m-> \u001B[39m\u001B[32m2795\u001B[39m \u001B[43m\u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mchunk\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mstream\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 2796\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[32m 2797\u001B[39m \u001B[43m \u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2798\u001B[39m \u001B[43m \u001B[49m\u001B[43mstream_mode\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstream_mode\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2799\u001B[39m \u001B[43m \u001B[49m\u001B[43moutput_keys\u001B[49m\u001B[43m=\u001B[49m\u001B[43moutput_keys\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2800\u001B[39m \u001B[43m \u001B[49m\u001B[43minterrupt_before\u001B[49m\u001B[43m=\u001B[49m\u001B[43minterrupt_before\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2801\u001B[39m \u001B[43m \u001B[49m\u001B[43minterrupt_after\u001B[49m\u001B[43m=\u001B[49m\u001B[43minterrupt_after\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2802\u001B[39m \u001B[43m \u001B[49m\u001B[43mcheckpoint_during\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcheckpoint_during\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2803\u001B[39m \u001B[43m \u001B[49m\u001B[43mdebug\u001B[49m\u001B[43m=\u001B[49m\u001B[43mdebug\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2804\u001B[39m \u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2805\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\u001B[43m:\u001B[49m\n\u001B[32m 2806\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43;01mif\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mstream_mode\u001B[49m\u001B[43m \u001B[49m\u001B[43m==\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mvalues\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\n\u001B[32m 2807\u001B[39m \u001B[43m \u001B[49m\u001B[43mlatest\u001B[49m\u001B[43m \u001B[49m\u001B[43m=\u001B[49m\u001B[43m \u001B[49m\u001B[43mchunk\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langgraph\\pregel\\__init__.py:2433\u001B[39m, in \u001B[36mPregel.stream\u001B[39m\u001B[34m(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, checkpoint_during, debug, subgraphs)\u001B[39m\n\u001B[32m 2427\u001B[39m \u001B[38;5;66;03m# Similarly to Bulk Synchronous Parallel / Pregel model\u001B[39;00m\n\u001B[32m 2428\u001B[39m \u001B[38;5;66;03m# computation proceeds in steps, while there are channel updates.\u001B[39;00m\n\u001B[32m 2429\u001B[39m \u001B[38;5;66;03m# Channel updates from step N are only visible in step N+1\u001B[39;00m\n\u001B[32m 2430\u001B[39m \u001B[38;5;66;03m# channels are guaranteed to be immutable for the duration of the step,\u001B[39;00m\n\u001B[32m 2431\u001B[39m \u001B[38;5;66;03m# with channel updates applied only at the transition between steps.\u001B[39;00m\n\u001B[32m 2432\u001B[39m \u001B[38;5;28;01mwhile\u001B[39;00m loop.tick(input_keys=\u001B[38;5;28mself\u001B[39m.input_channels):\n\u001B[32m-> \u001B[39m\u001B[32m2433\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43m_\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mrunner\u001B[49m\u001B[43m.\u001B[49m\u001B[43mtick\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 2434\u001B[39m \u001B[43m \u001B[49m\u001B[43mloop\u001B[49m\u001B[43m.\u001B[49m\u001B[43mtasks\u001B[49m\u001B[43m.\u001B[49m\u001B[43mvalues\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2435\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mstep_timeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2436\u001B[39m \u001B[43m \u001B[49m\u001B[43mretry_policy\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mretry_policy\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2437\u001B[39m \u001B[43m \u001B[49m\u001B[43mget_waiter\u001B[49m\u001B[43m=\u001B[49m\u001B[43mget_waiter\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 2438\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\u001B[43m:\u001B[49m\n\u001B[32m 2439\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;66;43;03m# emit output\u001B[39;49;00m\n\u001B[32m 2440\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43;01myield from\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43moutput\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 2441\u001B[39m \u001B[38;5;66;03m# emit output\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langgraph\\pregel\\runner.py:153\u001B[39m, in \u001B[36mPregelRunner.tick\u001B[39m\u001B[34m(self, tasks, reraise, timeout, retry_policy, get_waiter)\u001B[39m\n\u001B[32m 151\u001B[39m t = tasks[\u001B[32m0\u001B[39m]\n\u001B[32m 152\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m153\u001B[39m \u001B[43mrun_with_retry\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 154\u001B[39m \u001B[43m \u001B[49m\u001B[43mt\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 155\u001B[39m \u001B[43m \u001B[49m\u001B[43mretry_policy\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 156\u001B[39m \u001B[43m \u001B[49m\u001B[43mconfigurable\u001B[49m\u001B[43m=\u001B[49m\u001B[43m{\u001B[49m\n\u001B[32m 157\u001B[39m \u001B[43m \u001B[49m\u001B[43mCONFIG_KEY_CALL\u001B[49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[43mpartial\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 158\u001B[39m \u001B[43m \u001B[49m\u001B[43m_call\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 159\u001B[39m \u001B[43m \u001B[49m\u001B[43mweakref\u001B[49m\u001B[43m.\u001B[49m\u001B[43mref\u001B[49m\u001B[43m(\u001B[49m\u001B[43mt\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 160\u001B[39m \u001B[43m \u001B[49m\u001B[43mretry\u001B[49m\u001B[43m=\u001B[49m\u001B[43mretry_policy\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 161\u001B[39m \u001B[43m \u001B[49m\u001B[43mfutures\u001B[49m\u001B[43m=\u001B[49m\u001B[43mweakref\u001B[49m\u001B[43m.\u001B[49m\u001B[43mref\u001B[49m\u001B[43m(\u001B[49m\u001B[43mfutures\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 162\u001B[39m \u001B[43m \u001B[49m\u001B[43mschedule_task\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mschedule_task\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 163\u001B[39m \u001B[43m \u001B[49m\u001B[43msubmit\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43msubmit\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 164\u001B[39m \u001B[43m \u001B[49m\u001B[43mreraise\u001B[49m\u001B[43m=\u001B[49m\u001B[43mreraise\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 165\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 166\u001B[39m \u001B[43m \u001B[49m\u001B[43m}\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 167\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 168\u001B[39m \u001B[38;5;28mself\u001B[39m.commit(t, \u001B[38;5;28;01mNone\u001B[39;00m)\n\u001B[32m 169\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m exc:\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langgraph\\pregel\\retry.py:40\u001B[39m, in \u001B[36mrun_with_retry\u001B[39m\u001B[34m(task, retry_policy, configurable)\u001B[39m\n\u001B[32m 38\u001B[39m task.writes.clear()\n\u001B[32m 39\u001B[39m \u001B[38;5;66;03m# run the task\u001B[39;00m\n\u001B[32m---> \u001B[39m\u001B[32m40\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mtask\u001B[49m\u001B[43m.\u001B[49m\u001B[43mproc\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtask\u001B[49m\u001B[43m.\u001B[49m\u001B[43minput\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 41\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m ParentCommand \u001B[38;5;28;01mas\u001B[39;00m exc:\n\u001B[32m 42\u001B[39m ns: \u001B[38;5;28mstr\u001B[39m = config[CONF][CONFIG_KEY_CHECKPOINT_NS]\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langgraph\\utils\\runnable.py:623\u001B[39m, in \u001B[36mRunnableSeq.invoke\u001B[39m\u001B[34m(self, input, config, **kwargs)\u001B[39m\n\u001B[32m 621\u001B[39m \u001B[38;5;66;03m# run in context\u001B[39;00m\n\u001B[32m 622\u001B[39m \u001B[38;5;28;01mwith\u001B[39;00m set_config_context(config, run) \u001B[38;5;28;01mas\u001B[39;00m context:\n\u001B[32m--> \u001B[39m\u001B[32m623\u001B[39m \u001B[38;5;28minput\u001B[39m = \u001B[43mcontext\u001B[49m\u001B[43m.\u001B[49m\u001B[43mrun\u001B[49m\u001B[43m(\u001B[49m\u001B[43mstep\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 624\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 625\u001B[39m \u001B[38;5;28minput\u001B[39m = step.invoke(\u001B[38;5;28minput\u001B[39m, config)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langgraph\\utils\\runnable.py:377\u001B[39m, in \u001B[36mRunnableCallable.invoke\u001B[39m\u001B[34m(self, input, config, **kwargs)\u001B[39m\n\u001B[32m 375\u001B[39m run_manager.on_chain_end(ret)\n\u001B[32m 376\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m377\u001B[39m ret = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mfunc\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[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 378\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m.recurse \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(ret, Runnable):\n\u001B[32m 379\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m ret.invoke(\u001B[38;5;28minput\u001B[39m, config)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\agent.py:217\u001B[39m, in \u001B[36mget_graph..call_model\u001B[39m\u001B[34m(state)\u001B[39m\n\u001B[32m 215\u001B[39m prompt_answer = prompt_template.invoke(messages)\n\u001B[32m 216\u001B[39m \u001B[38;5;66;03m# invoke LLM\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m217\u001B[39m response = \u001B[43mllm_with_tools\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\u001B[43mprompt_answer\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 218\u001B[39m \u001B[38;5;28mprint\u001B[39m(\u001B[33m\"\u001B[39m\u001B[33mAgent has made a decision:\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[33m\"\u001B[39m, response.content, response.tool_calls)\n\u001B[32m 219\u001B[39m \u001B[38;5;28mprint\u001B[39m(\u001B[33m\"\u001B[39m\u001B[33mWaiting for 4 seconds...\u001B[39m\u001B[33m\"\u001B[39m)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_core\\runnables\\base.py:5416\u001B[39m, in \u001B[36mRunnableBindingBase.invoke\u001B[39m\u001B[34m(self, input, config, **kwargs)\u001B[39m\n\u001B[32m 5409\u001B[39m \u001B[38;5;129m@override\u001B[39m\n\u001B[32m 5410\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34minvoke\u001B[39m(\n\u001B[32m 5411\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m (...)\u001B[39m\u001B[32m 5414\u001B[39m **kwargs: Optional[Any],\n\u001B[32m 5415\u001B[39m ) -> Output:\n\u001B[32m-> \u001B[39m\u001B[32m5416\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mbound\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 5417\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[32m 5418\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_merge_configs\u001B[49m\u001B[43m(\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 5419\u001B[39m \u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43m{\u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m}\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 5420\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_google_genai\\chat_models.py:1175\u001B[39m, in \u001B[36mChatGoogleGenerativeAI.invoke\u001B[39m\u001B[34m(self, input, config, code_execution, stop, **kwargs)\u001B[39m\n\u001B[32m 1170\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 1171\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[32m 1172\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mTools are already defined.\u001B[39m\u001B[33m\"\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mcode_execution tool can\u001B[39m\u001B[33m'\u001B[39m\u001B[33mt be defined\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m 1173\u001B[39m )\n\u001B[32m-> \u001B[39m\u001B[32m1175\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43msuper\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[43m.\u001B[49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstop\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstop\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:369\u001B[39m, in \u001B[36mBaseChatModel.invoke\u001B[39m\u001B[34m(self, input, config, stop, **kwargs)\u001B[39m\n\u001B[32m 357\u001B[39m \u001B[38;5;129m@override\u001B[39m\n\u001B[32m 358\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34minvoke\u001B[39m(\n\u001B[32m 359\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m (...)\u001B[39m\u001B[32m 364\u001B[39m **kwargs: Any,\n\u001B[32m 365\u001B[39m ) -> BaseMessage:\n\u001B[32m 366\u001B[39m config = ensure_config(config)\n\u001B[32m 367\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m cast(\n\u001B[32m 368\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mChatGeneration\u001B[39m\u001B[33m\"\u001B[39m,\n\u001B[32m--> \u001B[39m\u001B[32m369\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mgenerate_prompt\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 370\u001B[39m \u001B[43m \u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_convert_input\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 371\u001B[39m \u001B[43m \u001B[49m\u001B[43mstop\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstop\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 372\u001B[39m \u001B[43m \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[43m=\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m.\u001B[49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mcallbacks\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 373\u001B[39m \u001B[43m \u001B[49m\u001B[43mtags\u001B[49m\u001B[43m=\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m.\u001B[49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mtags\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 374\u001B[39m \u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m=\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m.\u001B[49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mmetadata\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 375\u001B[39m \u001B[43m \u001B[49m\u001B[43mrun_name\u001B[49m\u001B[43m=\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m.\u001B[49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mrun_name\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 376\u001B[39m \u001B[43m \u001B[49m\u001B[43mrun_id\u001B[49m\u001B[43m=\u001B[49m\u001B[43mconfig\u001B[49m\u001B[43m.\u001B[49m\u001B[43mpop\u001B[49m\u001B[43m(\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mrun_id\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 377\u001B[39m \u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 378\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m.generations[\u001B[32m0\u001B[39m][\u001B[32m0\u001B[39m],\n\u001B[32m 379\u001B[39m ).message\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:946\u001B[39m, in \u001B[36mBaseChatModel.generate_prompt\u001B[39m\u001B[34m(self, prompts, stop, callbacks, **kwargs)\u001B[39m\n\u001B[32m 937\u001B[39m \u001B[38;5;129m@override\u001B[39m\n\u001B[32m 938\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mgenerate_prompt\u001B[39m(\n\u001B[32m 939\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m (...)\u001B[39m\u001B[32m 943\u001B[39m **kwargs: Any,\n\u001B[32m 944\u001B[39m ) -> LLMResult:\n\u001B[32m 945\u001B[39m prompt_messages = [p.to_messages() \u001B[38;5;28;01mfor\u001B[39;00m p \u001B[38;5;129;01min\u001B[39;00m prompts]\n\u001B[32m--> \u001B[39m\u001B[32m946\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mgenerate\u001B[49m\u001B[43m(\u001B[49m\u001B[43mprompt_messages\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstop\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstop\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:765\u001B[39m, in \u001B[36mBaseChatModel.generate\u001B[39m\u001B[34m(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)\u001B[39m\n\u001B[32m 762\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m i, m \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28menumerate\u001B[39m(input_messages):\n\u001B[32m 763\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m 764\u001B[39m results.append(\n\u001B[32m--> \u001B[39m\u001B[32m765\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_generate_with_cache\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 766\u001B[39m \u001B[43m \u001B[49m\u001B[43mm\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 767\u001B[39m \u001B[43m \u001B[49m\u001B[43mstop\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstop\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 768\u001B[39m \u001B[43m \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[43m=\u001B[49m\u001B[43mrun_managers\u001B[49m\u001B[43m[\u001B[49m\u001B[43mi\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[43mrun_managers\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01melse\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[32m 769\u001B[39m \u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 770\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 771\u001B[39m )\n\u001B[32m 772\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[32m 773\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m run_managers:\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:1011\u001B[39m, in \u001B[36mBaseChatModel._generate_with_cache\u001B[39m\u001B[34m(self, messages, stop, run_manager, **kwargs)\u001B[39m\n\u001B[32m 1009\u001B[39m result = generate_from_stream(\u001B[38;5;28miter\u001B[39m(chunks))\n\u001B[32m 1010\u001B[39m \u001B[38;5;28;01melif\u001B[39;00m inspect.signature(\u001B[38;5;28mself\u001B[39m._generate).parameters.get(\u001B[33m\"\u001B[39m\u001B[33mrun_manager\u001B[39m\u001B[33m\"\u001B[39m):\n\u001B[32m-> \u001B[39m\u001B[32m1011\u001B[39m result = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_generate\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1012\u001B[39m \u001B[43m \u001B[49m\u001B[43mmessages\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstop\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstop\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[43m=\u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\n\u001B[32m 1013\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1014\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 1015\u001B[39m result = \u001B[38;5;28mself\u001B[39m._generate(messages, stop=stop, **kwargs)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_google_genai\\chat_models.py:1242\u001B[39m, in \u001B[36mChatGoogleGenerativeAI._generate\u001B[39m\u001B[34m(self, messages, stop, run_manager, tools, functions, safety_settings, tool_config, generation_config, cached_content, tool_choice, **kwargs)\u001B[39m\n\u001B[32m 1216\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34m_generate\u001B[39m(\n\u001B[32m 1217\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m 1218\u001B[39m messages: List[BaseMessage],\n\u001B[32m (...)\u001B[39m\u001B[32m 1229\u001B[39m **kwargs: Any,\n\u001B[32m 1230\u001B[39m ) -> ChatResult:\n\u001B[32m 1231\u001B[39m request = \u001B[38;5;28mself\u001B[39m._prepare_request(\n\u001B[32m 1232\u001B[39m messages,\n\u001B[32m 1233\u001B[39m stop=stop,\n\u001B[32m (...)\u001B[39m\u001B[32m 1240\u001B[39m tool_choice=tool_choice,\n\u001B[32m 1241\u001B[39m )\n\u001B[32m-> \u001B[39m\u001B[32m1242\u001B[39m response: GenerateContentResponse = \u001B[43m_chat_with_retry\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1243\u001B[39m \u001B[43m \u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m=\u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1244\u001B[39m \u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1245\u001B[39m \u001B[43m \u001B[49m\u001B[43mgeneration_method\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mclient\u001B[49m\u001B[43m.\u001B[49m\u001B[43mgenerate_content\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1246\u001B[39m \u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mdefault_metadata\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1247\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1248\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m _response_to_result(response)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_google_genai\\chat_models.py:208\u001B[39m, in \u001B[36m_chat_with_retry\u001B[39m\u001B[34m(generation_method, **kwargs)\u001B[39m\n\u001B[32m 205\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[32m 206\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m e\n\u001B[32m--> \u001B[39m\u001B[32m208\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43m_chat_with_retry\u001B[49m\u001B[43m(\u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\tenacity\\__init__.py:338\u001B[39m, in \u001B[36mBaseRetrying.wraps..wrapped_f\u001B[39m\u001B[34m(*args, **kw)\u001B[39m\n\u001B[32m 336\u001B[39m copy = \u001B[38;5;28mself\u001B[39m.copy()\n\u001B[32m 337\u001B[39m wrapped_f.statistics = copy.statistics \u001B[38;5;66;03m# type: ignore[attr-defined]\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m338\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mcopy\u001B[49m\u001B[43m(\u001B[49m\u001B[43mf\u001B[49m\u001B[43m,\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[43m*\u001B[49m\u001B[43mkw\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\tenacity\\__init__.py:477\u001B[39m, in \u001B[36mRetrying.__call__\u001B[39m\u001B[34m(self, fn, *args, **kwargs)\u001B[39m\n\u001B[32m 475\u001B[39m retry_state = RetryCallState(retry_object=\u001B[38;5;28mself\u001B[39m, fn=fn, args=args, kwargs=kwargs)\n\u001B[32m 476\u001B[39m \u001B[38;5;28;01mwhile\u001B[39;00m \u001B[38;5;28;01mTrue\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m477\u001B[39m do = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43miter\u001B[49m\u001B[43m(\u001B[49m\u001B[43mretry_state\u001B[49m\u001B[43m=\u001B[49m\u001B[43mretry_state\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 478\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(do, DoAttempt):\n\u001B[32m 479\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\tenacity\\__init__.py:378\u001B[39m, in \u001B[36mBaseRetrying.iter\u001B[39m\u001B[34m(self, retry_state)\u001B[39m\n\u001B[32m 376\u001B[39m result = \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[32m 377\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m action \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mself\u001B[39m.iter_state.actions:\n\u001B[32m--> \u001B[39m\u001B[32m378\u001B[39m result = \u001B[43maction\u001B[49m\u001B[43m(\u001B[49m\u001B[43mretry_state\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 379\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m result\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\tenacity\\__init__.py:400\u001B[39m, in \u001B[36mBaseRetrying._post_retry_check_actions..\u001B[39m\u001B[34m(rs)\u001B[39m\n\u001B[32m 398\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34m_post_retry_check_actions\u001B[39m(\u001B[38;5;28mself\u001B[39m, retry_state: \u001B[33m\"\u001B[39m\u001B[33mRetryCallState\u001B[39m\u001B[33m\"\u001B[39m) -> \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[32m 399\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m (\u001B[38;5;28mself\u001B[39m.iter_state.is_explicit_retry \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mself\u001B[39m.iter_state.retry_run_result):\n\u001B[32m--> \u001B[39m\u001B[32m400\u001B[39m \u001B[38;5;28mself\u001B[39m._add_action_func(\u001B[38;5;28;01mlambda\u001B[39;00m rs: \u001B[43mrs\u001B[49m\u001B[43m.\u001B[49m\u001B[43moutcome\u001B[49m\u001B[43m.\u001B[49m\u001B[43mresult\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m)\n\u001B[32m 401\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m\n\u001B[32m 403\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m.after \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[36mFile \u001B[39m\u001B[32m~\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\concurrent\\futures\\_base.py:449\u001B[39m, in \u001B[36mFuture.result\u001B[39m\u001B[34m(self, timeout)\u001B[39m\n\u001B[32m 447\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m CancelledError()\n\u001B[32m 448\u001B[39m \u001B[38;5;28;01melif\u001B[39;00m \u001B[38;5;28mself\u001B[39m._state == FINISHED:\n\u001B[32m--> \u001B[39m\u001B[32m449\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m__get_result\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 451\u001B[39m \u001B[38;5;28mself\u001B[39m._condition.wait(timeout)\n\u001B[32m 453\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m._state \u001B[38;5;129;01min\u001B[39;00m [CANCELLED, CANCELLED_AND_NOTIFIED]:\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\concurrent\\futures\\_base.py:401\u001B[39m, in \u001B[36mFuture.__get_result\u001B[39m\u001B[34m(self)\u001B[39m\n\u001B[32m 399\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m._exception:\n\u001B[32m 400\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m401\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;28mself\u001B[39m._exception\n\u001B[32m 402\u001B[39m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[32m 403\u001B[39m \u001B[38;5;66;03m# Break a reference cycle with the exception in self._exception\u001B[39;00m\n\u001B[32m 404\u001B[39m \u001B[38;5;28mself\u001B[39m = \u001B[38;5;28;01mNone\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\tenacity\\__init__.py:480\u001B[39m, in \u001B[36mRetrying.__call__\u001B[39m\u001B[34m(self, fn, *args, **kwargs)\u001B[39m\n\u001B[32m 478\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(do, DoAttempt):\n\u001B[32m 479\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m480\u001B[39m result = \u001B[43mfn\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[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 481\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m: \u001B[38;5;66;03m# noqa: B902\u001B[39;00m\n\u001B[32m 482\u001B[39m retry_state.set_exception(sys.exc_info()) \u001B[38;5;66;03m# type: ignore[arg-type]\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\langchain_google_genai\\chat_models.py:190\u001B[39m, in \u001B[36m_chat_with_retry.._chat_with_retry\u001B[39m\u001B[34m(**kwargs)\u001B[39m\n\u001B[32m 187\u001B[39m \u001B[38;5;129m@retry_decorator\u001B[39m\n\u001B[32m 188\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34m_chat_with_retry\u001B[39m(**kwargs: Any) -> Any:\n\u001B[32m 189\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m190\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mgeneration_method\u001B[49m\u001B[43m(\u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 191\u001B[39m \u001B[38;5;66;03m# Do not retry for these errors.\u001B[39;00m\n\u001B[32m 192\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m google.api_core.exceptions.FailedPrecondition \u001B[38;5;28;01mas\u001B[39;00m exc:\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\google\\ai\\generativelanguage_v1beta\\services\\generative_service\\client.py:867\u001B[39m, in \u001B[36mGenerativeServiceClient.generate_content\u001B[39m\u001B[34m(self, request, model, contents, retry, timeout, metadata)\u001B[39m\n\u001B[32m 864\u001B[39m \u001B[38;5;28mself\u001B[39m._validate_universe_domain()\n\u001B[32m 866\u001B[39m \u001B[38;5;66;03m# Send the request.\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m867\u001B[39m response = \u001B[43mrpc\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 868\u001B[39m \u001B[43m \u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 869\u001B[39m \u001B[43m \u001B[49m\u001B[43mretry\u001B[49m\u001B[43m=\u001B[49m\u001B[43mretry\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 870\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 871\u001B[39m \u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m=\u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 872\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 874\u001B[39m \u001B[38;5;66;03m# Done; return the response.\u001B[39;00m\n\u001B[32m 875\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m response\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\google\\api_core\\gapic_v1\\method.py:131\u001B[39m, in \u001B[36m_GapicCallable.__call__\u001B[39m\u001B[34m(self, timeout, retry, compression, *args, **kwargs)\u001B[39m\n\u001B[32m 128\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m._compression \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[32m 129\u001B[39m kwargs[\u001B[33m\"\u001B[39m\u001B[33mcompression\u001B[39m\u001B[33m\"\u001B[39m] = compression\n\u001B[32m--> \u001B[39m\u001B[32m131\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mwrapped_func\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[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\google\\api_core\\retry\\retry_unary.py:293\u001B[39m, in \u001B[36mRetry.__call__..retry_wrapped_func\u001B[39m\u001B[34m(*args, **kwargs)\u001B[39m\n\u001B[32m 289\u001B[39m target = functools.partial(func, *args, **kwargs)\n\u001B[32m 290\u001B[39m sleep_generator = exponential_sleep_generator(\n\u001B[32m 291\u001B[39m \u001B[38;5;28mself\u001B[39m._initial, \u001B[38;5;28mself\u001B[39m._maximum, multiplier=\u001B[38;5;28mself\u001B[39m._multiplier\n\u001B[32m 292\u001B[39m )\n\u001B[32m--> \u001B[39m\u001B[32m293\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mretry_target\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 294\u001B[39m \u001B[43m \u001B[49m\u001B[43mtarget\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 295\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_predicate\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 296\u001B[39m \u001B[43m \u001B[49m\u001B[43msleep_generator\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 297\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_timeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 298\u001B[39m \u001B[43m \u001B[49m\u001B[43mon_error\u001B[49m\u001B[43m=\u001B[49m\u001B[43mon_error\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 299\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\google\\api_core\\retry\\retry_unary.py:144\u001B[39m, in \u001B[36mretry_target\u001B[39m\u001B[34m(target, predicate, sleep_generator, timeout, on_error, exception_factory, **kwargs)\u001B[39m\n\u001B[32m 142\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m sleep \u001B[38;5;129;01min\u001B[39;00m sleep_generator:\n\u001B[32m 143\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m144\u001B[39m result = \u001B[43mtarget\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 145\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m inspect.isawaitable(result):\n\u001B[32m 146\u001B[39m warnings.warn(_ASYNC_RETRY_WARNING)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\google\\api_core\\timeout.py:130\u001B[39m, in \u001B[36mTimeToDeadlineTimeout.__call__..func_with_timeout\u001B[39m\u001B[34m(*args, **kwargs)\u001B[39m\n\u001B[32m 126\u001B[39m remaining_timeout = \u001B[38;5;28mself\u001B[39m._timeout\n\u001B[32m 128\u001B[39m kwargs[\u001B[33m\"\u001B[39m\u001B[33mtimeout\u001B[39m\u001B[33m\"\u001B[39m] = remaining_timeout\n\u001B[32m--> \u001B[39m\u001B[32m130\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mfunc\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[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\google\\api_core\\grpc_helpers.py:76\u001B[39m, in \u001B[36m_wrap_unary_errors..error_remapped_callable\u001B[39m\u001B[34m(*args, **kwargs)\u001B[39m\n\u001B[32m 73\u001B[39m \u001B[38;5;129m@functools\u001B[39m.wraps(callable_)\n\u001B[32m 74\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34merror_remapped_callable\u001B[39m(*args, **kwargs):\n\u001B[32m 75\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m---> \u001B[39m\u001B[32m76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mcallable_\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[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 77\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m grpc.RpcError \u001B[38;5;28;01mas\u001B[39;00m exc:\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m exceptions.from_grpc_error(exc) \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mexc\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\grpc\\_interceptor.py:277\u001B[39m, in \u001B[36m_UnaryUnaryMultiCallable.__call__\u001B[39m\u001B[34m(self, request, timeout, metadata, credentials, wait_for_ready, compression)\u001B[39m\n\u001B[32m 268\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34m__call__\u001B[39m(\n\u001B[32m 269\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m 270\u001B[39m request: Any,\n\u001B[32m (...)\u001B[39m\u001B[32m 275\u001B[39m compression: Optional[grpc.Compression] = \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[32m 276\u001B[39m ) -> Any:\n\u001B[32m--> \u001B[39m\u001B[32m277\u001B[39m response, ignored_call = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_with_call\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 278\u001B[39m \u001B[43m \u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 279\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 280\u001B[39m \u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m=\u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 281\u001B[39m \u001B[43m \u001B[49m\u001B[43mcredentials\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcredentials\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 282\u001B[39m \u001B[43m \u001B[49m\u001B[43mwait_for_ready\u001B[49m\u001B[43m=\u001B[49m\u001B[43mwait_for_ready\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 283\u001B[39m \u001B[43m \u001B[49m\u001B[43mcompression\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcompression\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 284\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 285\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m response\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\grpc\\_interceptor.py:329\u001B[39m, in \u001B[36m_UnaryUnaryMultiCallable._with_call\u001B[39m\u001B[34m(self, request, timeout, metadata, credentials, wait_for_ready, compression)\u001B[39m\n\u001B[32m 326\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m exception: \u001B[38;5;66;03m# pylint:disable=broad-except\u001B[39;00m\n\u001B[32m 327\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m _FailureOutcome(exception, sys.exc_info()[\u001B[32m2\u001B[39m])\n\u001B[32m--> \u001B[39m\u001B[32m329\u001B[39m call = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_interceptor\u001B[49m\u001B[43m.\u001B[49m\u001B[43mintercept_unary_unary\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 330\u001B[39m \u001B[43m \u001B[49m\u001B[43mcontinuation\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mclient_call_details\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mrequest\u001B[49m\n\u001B[32m 331\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 332\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m call.result(), call\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\google\\ai\\generativelanguage_v1beta\\services\\generative_service\\transports\\grpc.py:79\u001B[39m, in \u001B[36m_LoggingClientInterceptor.intercept_unary_unary\u001B[39m\u001B[34m(self, continuation, client_call_details, request)\u001B[39m\n\u001B[32m 64\u001B[39m grpc_request = {\n\u001B[32m 65\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mpayload\u001B[39m\u001B[33m\"\u001B[39m: request_payload,\n\u001B[32m 66\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mrequestMethod\u001B[39m\u001B[33m\"\u001B[39m: \u001B[33m\"\u001B[39m\u001B[33mgrpc\u001B[39m\u001B[33m\"\u001B[39m,\n\u001B[32m 67\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mmetadata\u001B[39m\u001B[33m\"\u001B[39m: \u001B[38;5;28mdict\u001B[39m(request_metadata),\n\u001B[32m 68\u001B[39m }\n\u001B[32m 69\u001B[39m _LOGGER.debug(\n\u001B[32m 70\u001B[39m \u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[33mSending request for \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mclient_call_details.method\u001B[38;5;132;01m}\u001B[39;00m\u001B[33m\"\u001B[39m,\n\u001B[32m 71\u001B[39m extra={\n\u001B[32m (...)\u001B[39m\u001B[32m 76\u001B[39m },\n\u001B[32m 77\u001B[39m )\n\u001B[32m---> \u001B[39m\u001B[32m79\u001B[39m response = \u001B[43mcontinuation\u001B[49m\u001B[43m(\u001B[49m\u001B[43mclient_call_details\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 80\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m logging_enabled: \u001B[38;5;66;03m# pragma: NO COVER\u001B[39;00m\n\u001B[32m 81\u001B[39m response_metadata = response.trailing_metadata()\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\grpc\\_interceptor.py:315\u001B[39m, in \u001B[36m_UnaryUnaryMultiCallable._with_call..continuation\u001B[39m\u001B[34m(new_details, request)\u001B[39m\n\u001B[32m 306\u001B[39m (\n\u001B[32m 307\u001B[39m new_method,\n\u001B[32m 308\u001B[39m new_timeout,\n\u001B[32m (...)\u001B[39m\u001B[32m 312\u001B[39m new_compression,\n\u001B[32m 313\u001B[39m ) = _unwrap_client_call_details(new_details, client_call_details)\n\u001B[32m 314\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m315\u001B[39m response, call = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_thunk\u001B[49m\u001B[43m(\u001B[49m\u001B[43mnew_method\u001B[49m\u001B[43m)\u001B[49m\u001B[43m.\u001B[49m\u001B[43mwith_call\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 316\u001B[39m \u001B[43m \u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 317\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[43mnew_timeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 318\u001B[39m \u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m=\u001B[49m\u001B[43mnew_metadata\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 319\u001B[39m \u001B[43m \u001B[49m\u001B[43mcredentials\u001B[49m\u001B[43m=\u001B[49m\u001B[43mnew_credentials\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 320\u001B[39m \u001B[43m \u001B[49m\u001B[43mwait_for_ready\u001B[49m\u001B[43m=\u001B[49m\u001B[43mnew_wait_for_ready\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 321\u001B[39m \u001B[43m \u001B[49m\u001B[43mcompression\u001B[49m\u001B[43m=\u001B[49m\u001B[43mnew_compression\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 322\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 323\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m _UnaryOutcome(response, call)\n\u001B[32m 324\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m grpc.RpcError \u001B[38;5;28;01mas\u001B[39;00m rpc_error:\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\grpc\\_channel.py:1195\u001B[39m, in \u001B[36m_UnaryUnaryMultiCallable.with_call\u001B[39m\u001B[34m(self, request, timeout, metadata, credentials, wait_for_ready, compression)\u001B[39m\n\u001B[32m 1183\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mwith_call\u001B[39m(\n\u001B[32m 1184\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m 1185\u001B[39m request: Any,\n\u001B[32m (...)\u001B[39m\u001B[32m 1190\u001B[39m compression: Optional[grpc.Compression] = \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[32m 1191\u001B[39m ) -> Tuple[Any, grpc.Call]:\n\u001B[32m 1192\u001B[39m (\n\u001B[32m 1193\u001B[39m state,\n\u001B[32m 1194\u001B[39m call,\n\u001B[32m-> \u001B[39m\u001B[32m1195\u001B[39m ) = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_blocking\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1196\u001B[39m \u001B[43m \u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmetadata\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcredentials\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mwait_for_ready\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcompression\u001B[49m\n\u001B[32m 1197\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1198\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m _end_unary_response_blocking(state, call, \u001B[38;5;28;01mTrue\u001B[39;00m, \u001B[38;5;28;01mNone\u001B[39;00m)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\grpc\\_channel.py:1162\u001B[39m, in \u001B[36m_UnaryUnaryMultiCallable._blocking\u001B[39m\u001B[34m(self, request, timeout, metadata, credentials, wait_for_ready, compression)\u001B[39m\n\u001B[32m 1145\u001B[39m state.target = _common.decode(\u001B[38;5;28mself\u001B[39m._target)\n\u001B[32m 1146\u001B[39m call = \u001B[38;5;28mself\u001B[39m._channel.segregated_call(\n\u001B[32m 1147\u001B[39m cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,\n\u001B[32m 1148\u001B[39m \u001B[38;5;28mself\u001B[39m._method,\n\u001B[32m (...)\u001B[39m\u001B[32m 1160\u001B[39m \u001B[38;5;28mself\u001B[39m._registered_call_handle,\n\u001B[32m 1161\u001B[39m )\n\u001B[32m-> \u001B[39m\u001B[32m1162\u001B[39m event = \u001B[43mcall\u001B[49m\u001B[43m.\u001B[49m\u001B[43mnext_event\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1163\u001B[39m _handle_event(event, state, \u001B[38;5;28mself\u001B[39m._response_deserializer)\n\u001B[32m 1164\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m state, call\n", + "\u001B[36mFile \u001B[39m\u001B[32msrc\\\\python\\\\grpcio\\\\grpc\\\\_cython\\\\_cygrpc/channel.pyx.pxi:388\u001B[39m, in \u001B[36mgrpc._cython.cygrpc.SegregatedCall.next_event\u001B[39m\u001B[34m()\u001B[39m\n", + "\u001B[36mFile \u001B[39m\u001B[32msrc\\\\python\\\\grpcio\\\\grpc\\\\_cython\\\\_cygrpc/channel.pyx.pxi:211\u001B[39m, in \u001B[36mgrpc._cython.cygrpc._next_call_event\u001B[39m\u001B[34m()\u001B[39m\n", + "\u001B[36mFile \u001B[39m\u001B[32msrc\\\\python\\\\grpcio\\\\grpc\\\\_cython\\\\_cygrpc/channel.pyx.pxi:205\u001B[39m, in \u001B[36mgrpc._cython.cygrpc._next_call_event\u001B[39m\u001B[34m()\u001B[39m\n", + "\u001B[36mFile \u001B[39m\u001B[32msrc\\\\python\\\\grpcio\\\\grpc\\\\_cython\\\\_cygrpc/completion_queue.pyx.pxi:78\u001B[39m, in \u001B[36mgrpc._cython.cygrpc._latent_event\u001B[39m\u001B[34m()\u001B[39m\n", + "\u001B[36mFile \u001B[39m\u001B[32msrc\\\\python\\\\grpcio\\\\grpc\\\\_cython\\\\_cygrpc/completion_queue.pyx.pxi:61\u001B[39m, in \u001B[36mgrpc._cython.cygrpc._internal_latent_event\u001B[39m\u001B[34m()\u001B[39m\n", + "\u001B[36mFile \u001B[39m\u001B[32msrc\\\\python\\\\grpcio\\\\grpc\\\\_cython\\\\_cygrpc/completion_queue.pyx.pxi:42\u001B[39m, in \u001B[36mgrpc._cython.cygrpc._next\u001B[39m\u001B[34m()\u001B[39m\n", + "\u001B[31mKeyboardInterrupt\u001B[39m: " ] }, { - "data": { - "text/plain": [ - "{'messages': [HumanMessage(content='Search the web for the brith day of Friedrich Merz', additional_kwargs={}, response_metadata={}, id='1b56f817-9fc8-475c-b6c0-162dfeba5b83'),\n", - " HumanMessage(content='Write a plan how to solve this qustion?', additional_kwargs={}, response_metadata={}, id='d60f2d18-0c51-431b-90b1-851edf83e439'),\n", - " AIMessage(content='1. Search the web for \"Friedrich Merz birthday\".\\n2. Extract the date from the search results.\\n3. Provide the extracted date as the answer.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-bb9ba6a8-82db-48f5-919b-f05f3ea4b67f-0', usage_metadata={'input_tokens': 231, 'output_tokens': 34, 'total_tokens': 265, 'input_token_details': {'cache_read': 0}}),\n", - " HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={}, id='70a1709b-1067-40e9-bed6-6d081ce6efe5'),\n", - " AIMessage(content='', additional_kwargs={'function_call': {'name': 'web_search', 'arguments': '{\"query\": \"Friedrich Merz birthday\"}'}}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-3b477f1f-5d26-4a58-ae29-581bd4ffcd4e-0', tool_calls=[{'name': 'web_search', 'args': {'query': 'Friedrich Merz birthday'}, 'id': '5105ab7c-041e-4cef-b3c4-256092d9cc5c', 'type': 'tool_call'}], usage_metadata={'input_tokens': 493, 'output_tokens': 7, 'total_tokens': 500, 'input_token_details': {'cache_read': 0}}),\n", - " ToolMessage(content='Error: TypeError(\"BaseTool.invoke() missing 1 required positional argument: \\'input\\'\")\\n Please fix your mistakes.', name='web_search', id='0068624d-ff9e-4cb6-9415-273e489ae94e', tool_call_id='5105ab7c-041e-4cef-b3c4-256092d9cc5c', status='error'),\n", - " HumanMessage(content='Please provide me the answer to the question in detail.', additional_kwargs={}, response_metadata={}, id='024947cb-abd5-4f5a-9aab-63722a483271'),\n", - " AIMessage(content='I am sorry, I cannot fulfill this request. There was an error when calling the web_search tool. Please try again.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-70f8b036-ea1d-42e9-8d4b-f647ea13b31d-0', usage_metadata={'input_tokens': 540, 'output_tokens': 27, 'total_tokens': 567, 'input_token_details': {'cache_read': 0}}),\n", - " HumanMessage(content='Please provide me just the plain answer to the question', additional_kwargs={}, response_metadata={}, id='480e9cd8-0b33-4385-8450-7454fd9f0873'),\n", - " AIMessage(content='February 11, 1955', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.0-flash', 'safety_ratings': []}, id='run-3697ccf4-c694-4492-a07d-594497a381a9-0', usage_metadata={'input_tokens': 358, 'output_tokens': 10, 'total_tokens': 368, 'input_token_details': {'cache_read': 0}})],\n", - " 'aggregate': ['Plan', 'Agent', 'Agent', 'Answer']}" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001B[31m---------------------------------------------------------------------------\u001B[39m", + "\u001B[31mKeyboardInterrupt\u001B[39m Traceback (most recent call last)", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\async_helpers.py:128\u001B[39m, in \u001B[36m_pseudo_sync_runner\u001B[39m\u001B[34m(coro)\u001B[39m\n\u001B[32m 120\u001B[39m \u001B[38;5;250m\u001B[39m\u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 121\u001B[39m \u001B[33;03mA runner that does not really allow async execution, and just advance the coroutine.\u001B[39;00m\n\u001B[32m 122\u001B[39m \n\u001B[32m (...)\u001B[39m\u001B[32m 125\u001B[39m \u001B[33;03mCredit to Nathaniel Smith\u001B[39;00m\n\u001B[32m 126\u001B[39m \u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 127\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m128\u001B[39m \u001B[43mcoro\u001B[49m\u001B[43m.\u001B[49m\u001B[43msend\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m)\u001B[49m\n\u001B[32m 129\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mStopIteration\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m exc:\n\u001B[32m 130\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m exc.value\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:3384\u001B[39m, in \u001B[36mInteractiveShell.run_cell_async\u001B[39m\u001B[34m(self, raw_cell, store_history, silent, shell_futures, transformed_cell, preprocessing_exc_tuple, cell_id)\u001B[39m\n\u001B[32m 3380\u001B[39m exec_count = \u001B[38;5;28mself\u001B[39m.execution_count\n\u001B[32m 3381\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m result.error_in_exec:\n\u001B[32m 3382\u001B[39m \u001B[38;5;66;03m# Store formatted traceback and error details\u001B[39;00m\n\u001B[32m 3383\u001B[39m \u001B[38;5;28mself\u001B[39m.history_manager.exceptions[exec_count] = (\n\u001B[32m-> \u001B[39m\u001B[32m3384\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_format_exception_for_storage\u001B[49m\u001B[43m(\u001B[49m\u001B[43mresult\u001B[49m\u001B[43m.\u001B[49m\u001B[43merror_in_exec\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 3385\u001B[39m )\n\u001B[32m 3387\u001B[39m \u001B[38;5;66;03m# Each cell is a *single* input, regardless of how many lines it has\u001B[39;00m\n\u001B[32m 3388\u001B[39m \u001B[38;5;28mself\u001B[39m.execution_count += \u001B[32m1\u001B[39m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:3438\u001B[39m, in \u001B[36mInteractiveShell._format_exception_for_storage\u001B[39m\u001B[34m(self, exception, filename, running_compiled_code)\u001B[39m\n\u001B[32m 3435\u001B[39m stb = evalue._render_traceback_()\n\u001B[32m 3436\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 3437\u001B[39m \u001B[38;5;66;03m# Otherwise, use InteractiveTB to format the traceback.\u001B[39;00m\n\u001B[32m-> \u001B[39m\u001B[32m3438\u001B[39m stb = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mInteractiveTB\u001B[49m\u001B[43m.\u001B[49m\u001B[43mstructured_traceback\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 3439\u001B[39m \u001B[43m \u001B[49m\u001B[43metype\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mevalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtb\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtb_offset\u001B[49m\u001B[43m=\u001B[49m\u001B[32;43m1\u001B[39;49m\n\u001B[32m 3440\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 3441\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m:\n\u001B[32m 3442\u001B[39m \u001B[38;5;66;03m# In case formatting fails, fallback to Python's built-in formatting.\u001B[39;00m\n\u001B[32m 3443\u001B[39m stb = traceback.format_exception(etype, evalue, tb)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\ultratb.py:1182\u001B[39m, in \u001B[36mAutoFormattedTB.structured_traceback\u001B[39m\u001B[34m(self, etype, evalue, etb, tb_offset, context)\u001B[39m\n\u001B[32m 1180\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 1181\u001B[39m \u001B[38;5;28mself\u001B[39m.tb = etb\n\u001B[32m-> \u001B[39m\u001B[32m1182\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mFormattedTB\u001B[49m\u001B[43m.\u001B[49m\u001B[43mstructured_traceback\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1183\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43metype\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mevalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43metb\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtb_offset\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontext\u001B[49m\n\u001B[32m 1184\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\ultratb.py:1053\u001B[39m, in \u001B[36mFormattedTB.structured_traceback\u001B[39m\u001B[34m(self, etype, evalue, etb, tb_offset, context)\u001B[39m\n\u001B[32m 1050\u001B[39m mode = \u001B[38;5;28mself\u001B[39m.mode\n\u001B[32m 1051\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m mode \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mself\u001B[39m.verbose_modes:\n\u001B[32m 1052\u001B[39m \u001B[38;5;66;03m# Verbose modes need a full traceback\u001B[39;00m\n\u001B[32m-> \u001B[39m\u001B[32m1053\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mVerboseTB\u001B[49m\u001B[43m.\u001B[49m\u001B[43mstructured_traceback\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1054\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43metype\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mevalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43metb\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtb_offset\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontext\u001B[49m\n\u001B[32m 1055\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1056\u001B[39m \u001B[38;5;28;01melif\u001B[39;00m mode == \u001B[33m\"\u001B[39m\u001B[33mDocs\u001B[39m\u001B[33m\"\u001B[39m:\n\u001B[32m 1057\u001B[39m \u001B[38;5;66;03m# return DocTB\u001B[39;00m\n\u001B[32m 1058\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m DocTB(\n\u001B[32m 1059\u001B[39m theme_name=\u001B[38;5;28mself\u001B[39m._theme_name,\n\u001B[32m 1060\u001B[39m call_pdb=\u001B[38;5;28mself\u001B[39m.call_pdb,\n\u001B[32m (...)\u001B[39m\u001B[32m 1068\u001B[39m etype, evalue, etb, tb_offset, \u001B[32m1\u001B[39m\n\u001B[32m 1069\u001B[39m ) \u001B[38;5;66;03m# type: ignore[arg-type]\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\ultratb.py:861\u001B[39m, in \u001B[36mVerboseTB.structured_traceback\u001B[39m\u001B[34m(self, etype, evalue, etb, tb_offset, context)\u001B[39m\n\u001B[32m 852\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mstructured_traceback\u001B[39m(\n\u001B[32m 853\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m 854\u001B[39m etype: \u001B[38;5;28mtype\u001B[39m,\n\u001B[32m (...)\u001B[39m\u001B[32m 858\u001B[39m context: \u001B[38;5;28mint\u001B[39m = \u001B[32m5\u001B[39m,\n\u001B[32m 859\u001B[39m ) -> \u001B[38;5;28mlist\u001B[39m[\u001B[38;5;28mstr\u001B[39m]:\n\u001B[32m 860\u001B[39m \u001B[38;5;250m \u001B[39m\u001B[33;03m\"\"\"Return a nice text document describing the traceback.\"\"\"\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m861\u001B[39m formatted_exceptions: \u001B[38;5;28mlist\u001B[39m[\u001B[38;5;28mlist\u001B[39m[\u001B[38;5;28mstr\u001B[39m]] = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mformat_exception_as_a_whole\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 862\u001B[39m \u001B[43m \u001B[49m\u001B[43metype\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mevalue\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43metb\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontext\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtb_offset\u001B[49m\n\u001B[32m 863\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 865\u001B[39m termsize = \u001B[38;5;28mmin\u001B[39m(\u001B[32m75\u001B[39m, get_terminal_size()[\u001B[32m0\u001B[39m])\n\u001B[32m 866\u001B[39m theme = theme_table[\u001B[38;5;28mself\u001B[39m._theme_name]\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\ultratb.py:773\u001B[39m, in \u001B[36mVerboseTB.format_exception_as_a_whole\u001B[39m\u001B[34m(self, etype, evalue, etb, context, tb_offset)\u001B[39m\n\u001B[32m 763\u001B[39m frames.append(\n\u001B[32m 764\u001B[39m theme_table[\u001B[38;5;28mself\u001B[39m._theme_name].format(\n\u001B[32m 765\u001B[39m [\n\u001B[32m (...)\u001B[39m\u001B[32m 770\u001B[39m )\n\u001B[32m 771\u001B[39m )\n\u001B[32m 772\u001B[39m skipped = \u001B[32m0\u001B[39m\n\u001B[32m--> \u001B[39m\u001B[32m773\u001B[39m frames.append(\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mformat_record\u001B[49m\u001B[43m(\u001B[49m\u001B[43mrecord\u001B[49m\u001B[43m)\u001B[49m)\n\u001B[32m 774\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m skipped:\n\u001B[32m 775\u001B[39m frames.append(\n\u001B[32m 776\u001B[39m theme_table[\u001B[38;5;28mself\u001B[39m._theme_name].format(\n\u001B[32m 777\u001B[39m [\n\u001B[32m (...)\u001B[39m\u001B[32m 782\u001B[39m )\n\u001B[32m 783\u001B[39m )\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\ultratb.py:651\u001B[39m, in \u001B[36mVerboseTB.format_record\u001B[39m\u001B[34m(self, frame_info)\u001B[39m\n\u001B[32m 648\u001B[39m result += \u001B[33m\"\u001B[39m\u001B[33m, \u001B[39m\u001B[33m\"\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m call \u001B[38;5;28;01melse\u001B[39;00m \u001B[33m\"\u001B[39m\u001B[33m\"\u001B[39m\n\u001B[32m 649\u001B[39m result += \u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcall\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[33m\"\u001B[39m\n\u001B[32m 650\u001B[39m result += theme_table[\u001B[38;5;28mself\u001B[39m._theme_name].format(\n\u001B[32m--> \u001B[39m\u001B[32m651\u001B[39m \u001B[43m_format_traceback_lines\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 652\u001B[39m \u001B[43m \u001B[49m\u001B[43mframe_info\u001B[49m\u001B[43m.\u001B[49m\u001B[43mlines\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 653\u001B[39m \u001B[43m \u001B[49m\u001B[43mtheme_table\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_theme_name\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 654\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mhas_colors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 655\u001B[39m \u001B[43m \u001B[49m\u001B[43mlvals_toks\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 656\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 657\u001B[39m )\n\u001B[32m 658\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m result\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\IPython\\core\\tbtools.py:99\u001B[39m, in \u001B[36m_format_traceback_lines\u001B[39m\u001B[34m(lines, theme, has_colors, lvals_toks)\u001B[39m\n\u001B[32m 96\u001B[39m \u001B[38;5;28;01mcontinue\u001B[39;00m\n\u001B[32m 98\u001B[39m lineno = stack_line.lineno\n\u001B[32m---> \u001B[39m\u001B[32m99\u001B[39m line = \u001B[43mstack_line\u001B[49m\u001B[43m.\u001B[49m\u001B[43mrender\u001B[49m\u001B[43m(\u001B[49m\u001B[43mpygmented\u001B[49m\u001B[43m=\u001B[49m\u001B[43mhas_colors\u001B[49m\u001B[43m)\u001B[49m.rstrip(\u001B[33m\"\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[33m\"\u001B[39m) + \u001B[33m\"\u001B[39m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[33m\"\u001B[39m\n\u001B[32m 100\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m stack_line.is_current:\n\u001B[32m 101\u001B[39m \u001B[38;5;66;03m# This is the line with the error\u001B[39;00m\n\u001B[32m 102\u001B[39m pad = numbers_width - \u001B[38;5;28mlen\u001B[39m(\u001B[38;5;28mstr\u001B[39m(lineno))\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\stack_data\\core.py:391\u001B[39m, in \u001B[36mLine.render\u001B[39m\u001B[34m(self, markers, strip_leading_indent, pygmented, escape_html)\u001B[39m\n\u001B[32m 389\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m pygmented \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;28mself\u001B[39m.frame_info.scope:\n\u001B[32m 390\u001B[39m assert_(\u001B[38;5;129;01mnot\u001B[39;00m markers, \u001B[38;5;167;01mValueError\u001B[39;00m(\u001B[33m\"\u001B[39m\u001B[33mCannot use pygmented with markers\u001B[39m\u001B[33m\"\u001B[39m))\n\u001B[32m--> \u001B[39m\u001B[32m391\u001B[39m start_line, lines = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mframe_info\u001B[49m\u001B[43m.\u001B[49m\u001B[43m_pygmented_scope_lines\u001B[49m\n\u001B[32m 392\u001B[39m result = lines[\u001B[38;5;28mself\u001B[39m.lineno - start_line]\n\u001B[32m 393\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m strip_leading_indent:\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\stack_data\\utils.py:145\u001B[39m, in \u001B[36mcached_property.cached_property_wrapper\u001B[39m\u001B[34m(self, obj, _cls)\u001B[39m\n\u001B[32m 142\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m obj \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[32m 143\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\n\u001B[32m--> \u001B[39m\u001B[32m145\u001B[39m value = obj.\u001B[34m__dict__\u001B[39m[\u001B[38;5;28mself\u001B[39m.func.\u001B[34m__name__\u001B[39m] = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mfunc\u001B[49m\u001B[43m(\u001B[49m\u001B[43mobj\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 146\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m value\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\stack_data\\core.py:824\u001B[39m, in \u001B[36mFrameInfo._pygmented_scope_lines\u001B[39m\u001B[34m(self)\u001B[39m\n\u001B[32m 821\u001B[39m ranges = []\n\u001B[32m 823\u001B[39m code = atext.get_text(scope)\n\u001B[32m--> \u001B[39m\u001B[32m824\u001B[39m lines = \u001B[43m_pygmented_with_ranges\u001B[49m\u001B[43m(\u001B[49m\u001B[43mformatter\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcode\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mranges\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 826\u001B[39m start_line = \u001B[38;5;28mself\u001B[39m.source.line_range(scope)[\u001B[32m0\u001B[39m]\n\u001B[32m 828\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m start_line, lines\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\stack_data\\utils.py:164\u001B[39m, in \u001B[36m_pygmented_with_ranges\u001B[39m\u001B[34m(formatter, code, ranges)\u001B[39m\n\u001B[32m 161\u001B[39m length += \u001B[38;5;28mlen\u001B[39m(value)\n\u001B[32m 162\u001B[39m \u001B[38;5;28;01myield\u001B[39;00m ttype, value\n\u001B[32m--> \u001B[39m\u001B[32m164\u001B[39m lexer = \u001B[43mMyLexer\u001B[49m\u001B[43m(\u001B[49m\u001B[43mstripnl\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m)\u001B[49m\n\u001B[32m 165\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m 166\u001B[39m highlighted = pygments.highlight(code, lexer, formatter)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\lexer.py:660\u001B[39m, in \u001B[36mRegexLexerMeta.__call__\u001B[39m\u001B[34m(cls, *args, **kwds)\u001B[39m\n\u001B[32m 658\u001B[39m \u001B[38;5;28;01mpass\u001B[39;00m\n\u001B[32m 659\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m660\u001B[39m \u001B[38;5;28mcls\u001B[39m._tokens = \u001B[38;5;28;43mcls\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mprocess_tokendef\u001B[49m\u001B[43m(\u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43mcls\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mget_tokendefs\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 662\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mtype\u001B[39m.\u001B[34m__call__\u001B[39m(\u001B[38;5;28mcls\u001B[39m, *args, **kwds)\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\lexer.py:599\u001B[39m, in \u001B[36mRegexLexerMeta.process_tokendef\u001B[39m\u001B[34m(cls, name, tokendefs)\u001B[39m\n\u001B[32m 597\u001B[39m tokendefs = tokendefs \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mcls\u001B[39m.tokens[name]\n\u001B[32m 598\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m state \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mlist\u001B[39m(tokendefs):\n\u001B[32m--> \u001B[39m\u001B[32m599\u001B[39m \u001B[38;5;28;43mcls\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_process_state\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtokendefs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mprocessed\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstate\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 600\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m processed\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\lexer.py:563\u001B[39m, in \u001B[36mRegexLexerMeta._process_state\u001B[39m\u001B[34m(cls, unprocessed, processed, state)\u001B[39m\n\u001B[32m 560\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(tdef, include):\n\u001B[32m 561\u001B[39m \u001B[38;5;66;03m# it's a state reference\u001B[39;00m\n\u001B[32m 562\u001B[39m \u001B[38;5;28;01massert\u001B[39;00m tdef != state, \u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[33mcircular state reference \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mstate\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[33m\"\u001B[39m\n\u001B[32m--> \u001B[39m\u001B[32m563\u001B[39m tokens.extend(\u001B[38;5;28;43mcls\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_process_state\u001B[49m\u001B[43m(\u001B[49m\u001B[43munprocessed\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mprocessed\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 564\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43mstr\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mtdef\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m)\n\u001B[32m 565\u001B[39m \u001B[38;5;28;01mcontinue\u001B[39;00m\n\u001B[32m 566\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(tdef, _inherit):\n\u001B[32m 567\u001B[39m \u001B[38;5;66;03m# should be processed already, but may not in the case of:\u001B[39;00m\n\u001B[32m 568\u001B[39m \u001B[38;5;66;03m# 1. the state has no counterpart in any parent\u001B[39;00m\n\u001B[32m 569\u001B[39m \u001B[38;5;66;03m# 2. the state includes more than one 'inherit'\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\lexer.py:563\u001B[39m, in \u001B[36mRegexLexerMeta._process_state\u001B[39m\u001B[34m(cls, unprocessed, processed, state)\u001B[39m\n\u001B[32m 560\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(tdef, include):\n\u001B[32m 561\u001B[39m \u001B[38;5;66;03m# it's a state reference\u001B[39;00m\n\u001B[32m 562\u001B[39m \u001B[38;5;28;01massert\u001B[39;00m tdef != state, \u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[33mcircular state reference \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mstate\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[33m\"\u001B[39m\n\u001B[32m--> \u001B[39m\u001B[32m563\u001B[39m tokens.extend(\u001B[38;5;28;43mcls\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_process_state\u001B[49m\u001B[43m(\u001B[49m\u001B[43munprocessed\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mprocessed\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 564\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43mstr\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mtdef\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m)\n\u001B[32m 565\u001B[39m \u001B[38;5;28;01mcontinue\u001B[39;00m\n\u001B[32m 566\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(tdef, _inherit):\n\u001B[32m 567\u001B[39m \u001B[38;5;66;03m# should be processed already, but may not in the case of:\u001B[39;00m\n\u001B[32m 568\u001B[39m \u001B[38;5;66;03m# 1. the state has no counterpart in any parent\u001B[39;00m\n\u001B[32m 569\u001B[39m \u001B[38;5;66;03m# 2. the state includes more than one 'inherit'\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\lexer.py:579\u001B[39m, in \u001B[36mRegexLexerMeta._process_state\u001B[39m\u001B[34m(cls, unprocessed, processed, state)\u001B[39m\n\u001B[32m 576\u001B[39m \u001B[38;5;28;01massert\u001B[39;00m \u001B[38;5;28mtype\u001B[39m(tdef) \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28mtuple\u001B[39m, \u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[33mwrong rule def \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mtdef\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[33m\"\u001B[39m\n\u001B[32m 578\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m579\u001B[39m rex = \u001B[38;5;28;43mcls\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_process_regex\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtdef\u001B[49m\u001B[43m[\u001B[49m\u001B[32;43m0\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mrflags\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstate\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 580\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m err:\n\u001B[32m 581\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\u001B[33mf\u001B[39m\u001B[33m\"\u001B[39m\u001B[33muncompilable regex \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mtdef[\u001B[32m0\u001B[39m]\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[33m in state \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mstate\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[33m of \u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mcls\u001B[39m\u001B[38;5;132;01m!r}\u001B[39;00m\u001B[33m: \u001B[39m\u001B[38;5;132;01m{\u001B[39;00merr\u001B[38;5;132;01m}\u001B[39;00m\u001B[33m\"\u001B[39m) \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01merr\u001B[39;00m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\lexer.py:507\u001B[39m, in \u001B[36mRegexLexerMeta._process_regex\u001B[39m\u001B[34m(cls, regex, rflags, state)\u001B[39m\n\u001B[32m 505\u001B[39m \u001B[38;5;250m\u001B[39m\u001B[33;03m\"\"\"Preprocess the regular expression component of a token definition.\"\"\"\u001B[39;00m\n\u001B[32m 506\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(regex, Future):\n\u001B[32m--> \u001B[39m\u001B[32m507\u001B[39m regex = \u001B[43mregex\u001B[49m\u001B[43m.\u001B[49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 508\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m re.compile(regex, rflags).match\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\lexer.py:495\u001B[39m, in \u001B[36mwords.get\u001B[39m\u001B[34m(self)\u001B[39m\n\u001B[32m 494\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mget\u001B[39m(\u001B[38;5;28mself\u001B[39m):\n\u001B[32m--> \u001B[39m\u001B[32m495\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mregex_opt\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mwords\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mprefix\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mprefix\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43msuffix\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43msuffix\u001B[49m\u001B[43m)\u001B[49m\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:91\u001B[39m, in \u001B[36mregex_opt\u001B[39m\u001B[34m(strings, prefix, suffix)\u001B[39m\n\u001B[32m 83\u001B[39m \u001B[38;5;250m\u001B[39m\u001B[33;03m\"\"\"Return a compiled regex that matches any string in the given list.\u001B[39;00m\n\u001B[32m 84\u001B[39m \n\u001B[32m 85\u001B[39m \u001B[33;03mThe strings to match must be literal strings, not regexes. They will be\u001B[39;00m\n\u001B[32m (...)\u001B[39m\u001B[32m 88\u001B[39m \u001B[33;03m*prefix* and *suffix* are pre- and appended to the final regex.\u001B[39;00m\n\u001B[32m 89\u001B[39m \u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 90\u001B[39m strings = \u001B[38;5;28msorted\u001B[39m(strings)\n\u001B[32m---> \u001B[39m\u001B[32m91\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m prefix + \u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[43mstrings\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m(\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m + suffix\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(regex_opt_inner(\u001B[38;5;28mlist\u001B[39m(group[\u001B[32m1\u001B[39m]), \u001B[33m'\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36m\u001B[39m\u001B[34m(.0)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(\u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mlist\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mgroup\u001B[49m\u001B[43m[\u001B[49m\u001B[32;43m1\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(regex_opt_inner(\u001B[38;5;28mlist\u001B[39m(group[\u001B[32m1\u001B[39m]), \u001B[33m'\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36m\u001B[39m\u001B[34m(.0)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(\u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mlist\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mgroup\u001B[49m\u001B[43m[\u001B[49m\u001B[32;43m1\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(regex_opt_inner(\u001B[38;5;28mlist\u001B[39m(group[\u001B[32m1\u001B[39m]), \u001B[33m'\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36m\u001B[39m\u001B[34m(.0)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(\u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mlist\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mgroup\u001B[49m\u001B[43m[\u001B[49m\u001B[32;43m1\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:63\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 59\u001B[39m plen = \u001B[38;5;28mlen\u001B[39m(prefix)\n\u001B[32m 60\u001B[39m \u001B[38;5;66;03m# we have a prefix for all strings\u001B[39;00m\n\u001B[32m 61\u001B[39m \u001B[38;5;66;03m# print '-> prefix:', prefix\u001B[39;00m\n\u001B[32m 62\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + escape(prefix) \\\n\u001B[32m---> \u001B[39m\u001B[32m63\u001B[39m + \u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[43m[\u001B[49m\u001B[43ms\u001B[49m\u001B[43m[\u001B[49m\u001B[43mplen\u001B[49m\u001B[43m:\u001B[49m\u001B[43m]\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43ms\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mstrings\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m(?:\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m \\\n\u001B[32m 64\u001B[39m + close_paren\n\u001B[32m 65\u001B[39m \u001B[38;5;66;03m# is there a suffix?\u001B[39;00m\n\u001B[32m 66\u001B[39m strings_rev = [s[::-\u001B[32m1\u001B[39m] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings]\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:72\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 69\u001B[39m slen = \u001B[38;5;28mlen\u001B[39m(suffix)\n\u001B[32m 70\u001B[39m \u001B[38;5;66;03m# print '-> suffix:', suffix[::-1]\u001B[39;00m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m---> \u001B[39m\u001B[32m72\u001B[39m + \u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43msorted\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43ms\u001B[49m\u001B[43m[\u001B[49m\u001B[43m:\u001B[49m\u001B[43m-\u001B[49m\u001B[43mslen\u001B[49m\u001B[43m]\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43ms\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mstrings\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m(?:\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m 77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(regex_opt_inner(\u001B[38;5;28mlist\u001B[39m(group[\u001B[32m1\u001B[39m]), \u001B[33m'\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(regex_opt_inner(\u001B[38;5;28mlist\u001B[39m(group[\u001B[32m1\u001B[39m]), \u001B[33m'\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36m\u001B[39m\u001B[34m(.0)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(\u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mlist\u001B[39;49m\u001B[43m(\u001B[49m\u001B[43mgroup\u001B[49m\u001B[43m[\u001B[49m\u001B[32;43m1\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:63\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 59\u001B[39m plen = \u001B[38;5;28mlen\u001B[39m(prefix)\n\u001B[32m 60\u001B[39m \u001B[38;5;66;03m# we have a prefix for all strings\u001B[39;00m\n\u001B[32m 61\u001B[39m \u001B[38;5;66;03m# print '-> prefix:', prefix\u001B[39;00m\n\u001B[32m 62\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + escape(prefix) \\\n\u001B[32m---> \u001B[39m\u001B[32m63\u001B[39m + \u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[43m[\u001B[49m\u001B[43ms\u001B[49m\u001B[43m[\u001B[49m\u001B[43mplen\u001B[49m\u001B[43m:\u001B[49m\u001B[43m]\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43ms\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mstrings\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m(?:\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m \\\n\u001B[32m 64\u001B[39m + close_paren\n\u001B[32m 65\u001B[39m \u001B[38;5;66;03m# is there a suffix?\u001B[39;00m\n\u001B[32m 66\u001B[39m strings_rev = [s[::-\u001B[32m1\u001B[39m] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings]\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:39\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 36\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + escape(first) + close_paren\n\u001B[32m 37\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m first:\n\u001B[32m 38\u001B[39m \u001B[38;5;66;03m# print '-> first string empty'\u001B[39;00m\n\u001B[32m---> \u001B[39m\u001B[32m39\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \u001B[43mregex_opt_inner\u001B[49m\u001B[43m(\u001B[49m\u001B[43mstrings\u001B[49m\u001B[43m[\u001B[49m\u001B[32;43m1\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[33;43m'\u001B[39;49m\u001B[33;43m(?:\u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[43m)\u001B[49m \\\n\u001B[32m 40\u001B[39m + \u001B[33m'\u001B[39m\u001B[33m?\u001B[39m\u001B[33m'\u001B[39m + close_paren\n\u001B[32m 41\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(first) == \u001B[32m1\u001B[39m:\n\u001B[32m 42\u001B[39m \u001B[38;5;66;03m# multiple one-char strings? make a charset\u001B[39;00m\n\u001B[32m 43\u001B[39m oneletter = []\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36mregex_opt_inner\u001B[39m\u001B[34m(strings, open_paren)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(regex_opt_inner(\u001B[38;5;28mlist\u001B[39m(group[\u001B[32m1\u001B[39m]), \u001B[33m'\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[36mFile \u001B[39m\u001B[32m~\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\pygments\\regexopt.py:77\u001B[39m, in \u001B[36m\u001B[39m\u001B[34m(.0)\u001B[39m\n\u001B[32m 71\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren \\\n\u001B[32m 72\u001B[39m + regex_opt_inner(\u001B[38;5;28msorted\u001B[39m(s[:-slen] \u001B[38;5;28;01mfor\u001B[39;00m s \u001B[38;5;129;01min\u001B[39;00m strings), \u001B[33m'\u001B[39m\u001B[33m(?:\u001B[39m\u001B[33m'\u001B[39m) \\\n\u001B[32m 73\u001B[39m + escape(suffix[::-\u001B[32m1\u001B[39m]) + close_paren\n\u001B[32m 74\u001B[39m \u001B[38;5;66;03m# recurse on common 1-string prefixes\u001B[39;00m\n\u001B[32m 75\u001B[39m \u001B[38;5;66;03m# print '-> last resort'\u001B[39;00m\n\u001B[32m 76\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m open_paren + \\\n\u001B[32m---> \u001B[39m\u001B[32m77\u001B[39m \u001B[33m'\u001B[39m\u001B[33m|\u001B[39m\u001B[33m'\u001B[39m.join(regex_opt_inner(\u001B[38;5;28mlist\u001B[39m(group[\u001B[32m1\u001B[39m]), \u001B[33m'\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 78\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m group \u001B[38;5;129;01min\u001B[39;00m groupby(strings, \u001B[38;5;28;01mlambda\u001B[39;00m s: s[\u001B[32m0\u001B[39m] == first[\u001B[32m0\u001B[39m])) \\\n\u001B[32m 79\u001B[39m + close_paren\n", + "\u001B[31mKeyboardInterrupt\u001B[39m: " + ] } ], - "execution_count": 5 + "execution_count": 1 }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-30T09:50:08.495390Z", - "start_time": "2025-04-30T09:50:05.663936Z" - } - }, + "metadata": {}, "cell_type": "code", - "source": "search_docs = TavilySearchResults(max_results=3).invoke({'query': 'who won the last french open'})", + "source": "search_docs = TavilySearchResults(max_results=3).invoke({'query': 'Friedrich Merz birthday'})", "id": "bf74512499009afd", "outputs": [], - "execution_count": 7 + "execution_count": null }, { - "metadata": { - "ExecuteTime": { - "end_time": "2025-04-30T09:50:11.782505Z", - "start_time": "2025-04-30T09:50:11.773627Z" - } - }, + "metadata": {}, "cell_type": "code", - "source": "search_docs", + "source": [ + "serialized = \"\\n\\n\".join(\n", + " (f\"\\nContent:\\n{search_docs.page_content}\")\n", + " for doc in docs\n", + " )\n", + "serialized" + ], "id": "a0c1339790a66002", - "outputs": [ - { - "data": { - "text/plain": [ - "[{'title': \"List of French Open men's singles champions - Wikipedia\",\n", - " 'url': 'https://en.wikipedia.org/wiki/List_of_French_Open_men%27s_singles_champions',\n", - " 'content': \"Country | Amateur Era | Open Era | All-time | First title | Last title\\nFrance(FRA) | 37 | 1 | 38 | 1892 | 1983\\nSpain(ESP) | 2 | 21 | 23 | 1961 | 2024\\nAustralia(AUS) | 9 | 2 | 11 | 1933 | 1969\\nUnited States(USA) | 7 | 4 | 11 | 1938 | 1999\\nSweden(SWE) | 1 | 9 | 10 | 1957 | 1988\\nCzechoslovakia(TCH)[h] | 0 | 5 | 5 | 1970 | 1987\\nGermany(GER) | 3 | 0 | 3 | 1934 | 1937\\nItaly(ITA) | 2 | 1 | 3 | 1959 | 1976\\nBrazil(BRA) | 0 | 3 | 3 | 1997 | 2001\\nSerbia(SRB) | 0 | 3 | 3 | 2016 | 2023 [...] Location | Paris[a]France\\nVenue | Stade Roland Garros\\nGoverning body | Fédération Française de Tennis(FFT)\\nCreated | 1891 (established)1925 (Grand Slamevent)\\nEditions | 128 events (2024)94Grand Slamevents (since1925)57 events (Open Era)\\nSurface | Red clay(since 1908)Sand / Clay (1892–1907)Grass (1891)\\nTrophy | Coupe des Mousquetaires\\nWebsite | French Open champions\\nMost titles\\n14:Rafael Nadal\\nCurrent champion\\nCarlos Alcaraz(First title) [...] Open Era, who won the 2023 French Open at 36 years, twenty days.[8] French players have won the most French Open men's singles titles, with 38 victories, followed by players from Spain (20) and Australia (11). The current champion is Carlos Alcaraz, who beat Alexander Zverev in the 2024 final.[9]\",\n", - " 'score': 0.8190992},\n", - " {'title': 'French Open | History, Winners, & Facts | Britannica',\n", - " 'url': 'https://www.britannica.com/sports/French-Open',\n", - " 'content': '2014 | Julien Benneteau, Edouard Roger-Vasselin | Su-Wei Hsieh, Shuai Peng\\n2015 | Ivan Dodig, Marcelo Melo | Bethanie Mattek-Sands, Lucie Safarova\\n2016 | Feliciano Lopez, Marc Lopez | Caroline Garcia, Kristina Mladenovic\\n2017 | Ryan Harrison, Michael Venus | Bethanie Mattek-Sands, Lucie Safarova\\n2018 | Pierre-Hugues Herbert, Nicolas Mahut | Barbora Krejcikova, Katerina Siniakova\\n2019 | Kevin Krawietz, Andreas Mies | Timea Babos, Kristina Mladenovic [...] 2017 | Rafael Nadal (Spain) | Jelena Ostapenko (Latvia)\\n2018 | Rafael Nadal (Spain) | Simona Halep (Rom.)\\n2019 | Rafael Nadal (Spain) | Ashleigh Barty (Austl.)\\n2020 | Rafael Nadal (Spain) | Iga Świątek (Pol.)\\n2021 | Novak Djokovic (Serbia) | Barbora Krejčíková (Czech.)\\n2022 | Rafael Nadal (Spain) | Iga Świątek (Pol.)\\n2023 | Novak Djokovic (Serbia) | Iga Świątek (Pol.)\\n2024 | Carlos Alcaraz (Spain) | Iga Świątek (Pol.)\\nWinners of the French Open doubles championship are provided in the table. [...] 2007 | Mark Knowles, Daniel Nestor | Alicia Molik, Mara Santangelo\\n2008 | Pablo Cuevas, Luis Horna | Anabel Medina Garrigues, Virginia Ruano Pascual\\n2009 | Lukas Dlouhy, Leander Paes | Anabel Medina Garrigues, Virginia Ruano Pascual\\n2010 | Daniel Nestor, Nenad Zimonjic | Serena Williams, Venus Williams\\n2011 | Max Mirnyi, Daniel Nestor | Andrea Hlavackova, Lucie Hradecka\\n2012 | Max Mirnyi, Daniel Nestor | Sara Errani, Roberta Vinci\\n2013 | Bob Bryan, Mike Bryan | Ekaterina Makarova, Elena Vesnina',\n", - " 'score': 0.783542},\n", - " {'title': \"Winners of the Men's French Open - Tennis - Topend Sports\",\n", - " 'url': 'https://www.topendsports.com/events/tennis-grand-slam/french-open/winners-men.htm',\n", - " 'content': \"Home > Events > Tennis > Grand Slam > French Open > Winners > Men\\n\\nWinners of the Men's French Open\\n\\nHere are all the winners of the French Tennis Open men's title since the first tournament in 1925. The recent tournaments have been dominated by Spanish player Rafael Nadal. He now has 14 French Open men's singles titles (the last in 2022). See also the Women's Singles Results.\",\n", - " 'score': 0.77446437}]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "source": "search_docs = TavilySearchResults(max_results=3).invoke({'query': 'Friedrich Merz birthday'})\n", + "id": "bdab71ec26eaadc0", + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "for doc in search_docs:\n", + " # print(f'Titel: {doc[\"title\"]}\\nContent: {doc[\"content\"]}')\n", + " print(doc[\"url\"])" ], - "execution_count": 8 + "id": "8a438fd3c32aec47", + "outputs": [], + "execution_count": null }, { "metadata": {}, "cell_type": "code", + "source": [ + "formatted_search_docs = \"\\n\\n---\\n\\n\".join(\n", + " [\n", + " f'URL: {doc[\"url\"]}\\nTitle= {doc[\"title\"]}\\nContent: {doc[\"content\"]}'\n", + " for doc in search_docs\n", + " ])" + ], + "id": "ddc6663672322015", "outputs": [], - "execution_count": null, + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "source": "formatted_search_docs", + "id": "ab516e3c391c5d6d", + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", "source": "", - "id": "bdab71ec26eaadc0" + "id": "5130c97cec9d8740", + "outputs": [], + "execution_count": null } ], "metadata": {