{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "882gPGOGM7-i"
      },
      "source": [
        "# Optimizing Agent Prompts with GEPA on Tau-bench\n",
        "\n",
        "This demo notebook walks you through optimizing an AI agent's prompt using the\n",
        "**Genetic-Pareto (GEPA)** algorithm. We'll use the Google Agent Development\n",
        "Kit (ADK) to build and run our agent in **Tau-bench**, a benchmark designed to\n",
        "test agents in realistic, conversational scenarios involving tool use and\n",
        "adherence to policies.\n",
        "\n",
        "**Goal:** To take a simple, underperforming prompt and automatically\n",
        "improve it using GEPA, increasing the agent's reliability on a customer\n",
        "support task.\n",
        "\n",
        "**Note:** You can find more options to run GEPA with an ADK agent in the [README file](https://github.com/google/adk-python/blob/main/contributing/samples/gepa/README.md).\n",
        "\n",
        "## Prerequisites\n",
        "\n",
        "*   **Google Cloud Project:** You'll need access to a Google Cloud Project with\n",
        "    Vertex AI enabled to run the language models.\n",
        "*   **Installation:** Ensure `google-adk`, `tau-bench`, and\n",
        "    `google-cloud-aiplatform` are installed.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "GqUHYdvRJ7pt",
        "language": "python",
        "cellView": "form"
      },
      "outputs": [],
      "source": [
        "# @title Install Tau-bench and GEPA\n",
        "!git clone https://github.com/google/adk-python.git\n",
        "!git clone https://github.com/sierra-research/tau-bench.git\n",
        "%cd tau-bench/\n",
        "!pip install -e . --quiet\n",
        "\n",
        "%cd ..\n",
        "!pip install gepa --quiet\n",
        "\n",
        "!pip install retry --quiet"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# @title Configure python dependencies\n",
        "import sys\n",
        "\n",
        "sys.path.append('/content/tau-bench')\n",
        "sys.path.append('/content/adk-python/contributing/samples/gepa')"
      ],
      "metadata": {
        "cellView": "form",
        "id": "k0nrsIca0yXr"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# @title Authentication\n",
        "from google.colab import auth\n",
        "\n",
        "auth.authenticate_user()"
      ],
      "metadata": {
        "cellView": "form",
        "id": "NsXa217t03vL"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "SdGCJfEtz8Nq",
        "cellView": "form"
      },
      "outputs": [],
      "source": [
        "# @title Setup\n",
        "from datetime import datetime\n",
        "import json\n",
        "import logging\n",
        "import os\n",
        "\n",
        "import experiment as experiment_lib\n",
        "from google.genai import types\n",
        "import utils\n",
        "\n",
        "\n",
        "# @markdown ### ☁️ Configure Vertex AI Access\n",
        "# @markdown Enter your Google Cloud Project ID and Location.\n",
        "\n",
        "# @markdown Configure Vertex AI Access\n",
        "\n",
        "GCP_PROJECT = ''  # @param {type: 'string'}\n",
        "GCP_LOCATION = 'us-central1'  # @param {type: 'string'}\n",
        "\n",
        "# @markdown ---\n",
        "# @markdown ### 🧠 Configure LLM Models\n",
        "# @markdown We recommend starting with Flash models for speed and cost-efficiency\n",
        "# @markdown during optimization, but larger models like `gemini-1.5-pro` can also\n",
        "# @markdown be used, especially for the reflection model.\n",
        "AGENT_MODEL_NAME = 'gemini-2.5-flash'  # @param {type: 'string'}\n",
        "USER_MODEL_NAME = 'gemini-2.5-flash'  # @param {type: 'string'}\n",
        "REFLECTION_MODEL_NAME = 'gemini-2.5-pro'  # @param {type: 'string'}\n",
        "\n",
        "# @markdown ---\n",
        "# @markdown ### ⚙️ Configure Experiment Parameters\n",
        "# @markdown Number of trajectories sampled from rollouts to be used by the reflection model in each GEPA step:\n",
        "MINI_BATCH_SIZE = 8  # @param {type: 'integer'}\n",
        "# @markdown Size of the pareto and feedback datasets (small setting for demo purposes):\n",
        "MAX_DATASET_SIZE = 10  # @param {type: 'integer'}\n",
        "# @markdown Number of times each task is run during evaluation:\n",
        "NUM_EVAL_TRIALS = 4  # @param {type: 'integer'}\n",
        "# @markdown Total budget for GEPA prompt evaluations:\n",
        "MAX_METRIC_CALLS = 100  # @param {type: 'integer'}\n",
        "# @markdown Maximum number of parallel agent-environment interactions\n",
        "MAX_CONCURRENCY = 4  # @param {type: 'integer'}\n",
        "\n",
        "# @markdown **Note:** You can find more information on how to configure GEPA in the [README file](https://github.com/google/adk-python/blob/main/contributing/samples/gepa/README.md).\n",
        "\n",
        "# The ADK uses these environment variables to connect to Vertex AI via the\n",
        "# Google GenAI SDK.\n",
        "os.environ['GOOGLE_GENAI_USE_VERTEXAI'] = 'true'\n",
        "os.environ['GOOGLE_CLOUD_PROJECT'] = GCP_PROJECT\n",
        "os.environ['GOOGLE_CLOUD_LOCATION'] = GCP_LOCATION\n",
        "\n",
        "# Set a logging verbosity suited for this experiment. See\n",
        "# https://github.com/google/adk-python/issues/1852 for context\n",
        "types.logger.addFilter(utils.FilterInferenceWarnings())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HbKlznZHvskm"
      },
      "source": [
        "# Initial Inference: A First Look at Our Agent\n",
        "\n",
        "Before we start optimizing, let's see how our agent performs with a very basic\n",
        "prompt. This will help us understand the task and see what a failure case looks\n",
        "like.\n",
        "\n",
        "**The Task:** We're using the **'retail'** environment from Tau-bench. In this\n",
        "environment, our agent acts as a customer support agent for an online store. It\n",
        "needs to use a set of tools (like `check_order_status`, `issue_refund`, etc.)\n",
        "to help a simulated user resolve their issues, while following specific support\n",
        "policies (e.g., only refunding orders less than 30 days old).\n",
        "\n",
        "**Our Agent:** The agent is built with ADK using a standard tool-calling\n",
        "strategy. It receives the conversation history and a list of available tools,\n",
        "and it must decide whether to respond to the user or call a tool.\n",
        "\n",
        "**The Initial Prompt:** We'll start with a simple, one-line instruction. As\n",
        "we'll see, this is often not enough for an agent to perform reliably in complex\n",
        "scenarios."
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# @title Define an initial instruction\n",
        "\n",
        "# @markdown This is our starting \"seed\" prompt. It's very generic and doesn't give the agent much guidance on how to behave or use tools.\n",
        "BASE_SYSTEM_INSTRUCTION = 'you are a customer support agent helping customers resolve their issues by using the right tools'  # @param {type: 'string'}\n",
        "\n",
        "print(BASE_SYSTEM_INSTRUCTION)"
      ],
      "metadata": {
        "id": "U8FyG4ep1OLW",
        "cellView": "form"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "GNlTPbCXvskn",
        "outputId": "02514309-4027-4760-9724-b8cadfbf7c86",
        "cellView": "form"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Loading user with strategy: llm\n",
            "Running tasks [1, 2, 9, 12] (checkpoint path: results/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104135627.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Unclosed client session\n",
            "client_session: <aiohttp.client.ClientSession object at 0x7f815a2b2b50>\n",
            "Unclosed connector\n",
            "connections: ['deque([(<aiohttp.client_proto.ResponseHandler object at 0x7f815ad61f60>, 95679.854398078)])']\n",
            "connector: <aiohttp.connector.TCPConnector object at 0x7f815958ced0>\n",
            "Unclosed client session\n",
            "client_session: <aiohttp.client.ClientSession object at 0x7f815820d410>\n",
            "Unclosed connector\n",
            "connections: ['deque([(<aiohttp.client_proto.ResponseHandler object at 0x7f815aa7dda0>, 95859.665770103)])']\n",
            "connector: <aiohttp.connector.TCPConnector object at 0x7f816149bdd0>\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.25\n",
            "📈 Pass^k\n",
            "  k=1: 0.25\n",
            "\n",
            "📄 Results saved to results/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104135627.json\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# @title Initial Inference: A First Look at Our Agent\n",
        "\n",
        "from tau_bench.types import EnvRunResult, RunConfig\n",
        "\n",
        "# We will run our ADK agent on two tasks from the Tau-bench 'dev' set.\n",
        "# The `run_tau_bench_rollouts` function handles the interaction between the\n",
        "# agent and the simulated user environment.\n",
        "print('Running initial inference for tasks 1 and 2...')\n",
        "inference_results = experiment_lib.run_tau_bench_rollouts(\n",
        "    config=RunConfig(\n",
        "        env='retail',\n",
        "        model=AGENT_MODEL_NAME,\n",
        "        model_provider='vertex_ai',\n",
        "        user_model=USER_MODEL_NAME,\n",
        "        user_model_provider='vertex_ai',\n",
        "        agent_strategy='tool-calling',\n",
        "        user_strategy='llm',  # The user is simulated by an LLM\n",
        "        max_concurrency=MAX_CONCURRENCY,\n",
        "        task_ids=[\n",
        "            1,\n",
        "            2,\n",
        "        ],  # We'll just run two specific tasks for this initial look\n",
        "        task_split='dev',\n",
        "    ),\n",
        "    system_instruction=BASE_SYSTEM_INSTRUCTION,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "B3ZEiRgZvskn",
        "outputId": "804df2c6-964e-4982-e298-64d14ba2d84e",
        "cellView": "form"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "--- Trajectory Example ---\n",
            "**SYSTEM**: you are a customer support agent helping customers resolve their issues by using the right tools\n",
            "\n",
            "**USER**: Hello. I need to make an exchange regarding a recent order I received.\n",
            "\n",
            "**MODEL**: I can help you with that. What is the order ID?\n",
            "\n",
            "**USER**: The order ID is #W7273336.\n",
            "\n",
            "**MODEL**: Okay, you want to exchange items from order #W7273336.\n",
            "\n",
            "Could you please tell me:\n",
            "1. What are the item IDs of the products you wish to exchange?\n",
            "2. What are the item IDs of the new products you would like to receive?\n",
            "3. What payment method would you like to use to cover any price differences or receive refunds (e.g., gift card, credit card)?\n",
            "\n",
            "**USER**: I don't have the specific item IDs at hand, but I can describe the products. I received a black laser gaming mouse and a 4-foot metal bookshelf. I need to exchange both of these.\n",
            "\n",
            "**MODEL**: I understand. Since you don't have the item IDs, I'll need to look up the order details to identify them.\n",
            "\n",
            "\n",
            "**MODEL**: 📞 Tool Call: `get_order_details(order_id='#W7273336')`\n",
            "\n",
            "**USER**: ↪️ Tool Response from `get_order_details`: `{\"order_id\": \"#W7273336\", \"user_id\": \"omar_lopez_3107\", \"address\": {\"address1\": \"959 Broadway\", \"address2\": \"Suite 363\", \"city\": \"Los Angeles\", \"country\": \"USA\", \"state\": \"CA\", \"zip\": \"90339\"}, \"items\": [{\"name\": \"Espresso Machine\", \"product_id\": \"4354588079\", \"item_id\": \"6200867091\", \"price\": 2955.17, \"options\": {\"pressure\": \"19 bar\", \"capacity\": \"1L\", \"type\": \"capsule\"}}, {\"name\": \"Bookshelf\", \"product_id\": \"8600330539\", \"item_id\": \"8018699955\", \"price\": 467.86, \"options\": {\"material\": \"metal\", \"color\": \"brown\", \"height\": \"4 ft\"}}, {\"name\": \"Gaming Mouse\", \"product_id\": \"5713490933\", \"item_id\": \"8214883393\", \"price\": 150.58, \"options\": {\"color\": \"black\", \"sensor type\": \"laser\", \"connectivity\": \"wireless\"}}, {\"name\": \"Pet Bed\", \"product_id\": \"2747247837\", \"item_id\": \"6857426243\", \"price\": 196.53, \"options\": {\"size\": \"medium\", \"material\": \"fleece\", \"color\": \"grey\"}}, {\"name\": \"Air Purifier\", \"product_id\": \"3821016478\", \"item_id\": \"9375701158\", \"price\": 489.5, \"options\": {\"room size\": \"medium\", \"filter type\": \"carbon\", \"features\": \"quiet operation\"}}], \"fulfillments\": [{\"tracking_id\": [\"555296392986\"], \"item_ids\": [\"6200867091\", \"8018699955\", \"8214883393\", \"6857426243\", \"9375701158\"]}], \"status\": \"delivered\", \"payment_history\": [{\"transaction_type\": \"payment\", \"amount\": 4259.64, \"payment_method_id\": \"paypal_1530316\"}]}`\n",
            "\n",
            "**MODEL**: Thank you for waiting. I've looked up the details for order #W7273336.\n",
            "\n",
            "The item ID for the black laser gaming mouse is **8214883393**.\n",
            "The item ID for the 4-foot metal bookshelf is **8018699955**.\n",
            "\n",
            "Now, please tell me:\n",
            "1. What are the item IDs of the new gaming mouse and bookshelf you would like to receive?\n",
            "2. What payment method would you like to use to cover any price differences or receive refunds (e.g., gift card, credit card)? The original payment method for this order was PayPal, with `payment_method_id`: \"paypal_1530316\")?\n",
            "\n",
            "**USER**: Thank you for providing those. I need to exchange the black laser gaming mouse (item ID 8214883393). I'd like to get a white optical mouse instead. The black doesn't suit my setup, and I prefer optical over laser. I don't care if it's wired or wireless, just whichever is cheaper.\n",
            "\n",
            "As for the 4-foot metal bookshelf (item ID 8018699955), it's just too short. I need a taller one. I want to exchange it for a 5-feet tall glass bookshelf.\n",
            "\n",
            "Regarding the glass bookshelf, I'm not sure about the color yet. What are the available color options for the 5-feet glass bookshelves? As for payment, we can discuss that once we figure out the replacement items.\n",
            "\n",
            "**MODEL**: Okay, I understand. You want to exchange the black laser gaming mouse (item ID 8214883393) for a white optical mouse, and the 4-foot metal bookshelf (item ID 8018699955) for a 5-foot tall glass bookshelf.\n",
            "\n",
            "Let's find the options for these. First, I'll look up the product types to find suitable replacements.\n",
            "\n",
            "\n",
            "**MODEL**: 📞 Tool Call: `list_all_product_types()`\n",
            "\n",
            "**USER**: ↪️ Tool Response from `list_all_product_types`: `{\"Action Camera\": \"3377618313\", \"Air Purifier\": \"3821016478\", \"Backpack\": \"2524789262\", \"Bicycle\": \"9783735446\", \"Bluetooth Speaker\": \"4768869376\", \"Bookshelf\": \"8600330539\", \"Coffee Maker\": \"7996920482\", \"Cycling Helmet\": \"7765186836\", \"Desk Lamp\": \"6817146515\", \"Digital Camera\": \"8940227892\", \"Dumbbell Set\": \"7233192239\", \"E-Reader\": \"3801771308\", \"Electric Kettle\": \"1075968781\", \"Electric Toothbrush\": \"7352963235\", \"Espresso Machine\": \"4354588079\", \"Fleece Jacket\": \"8560156827\", \"Gaming Mouse\": \"5713490933\", \"Garden Hose\": \"6679515468\", \"Grill\": \"6819683148\", \"Headphones\": \"6992792935\", \"Hiking Boots\": \"7363354090\", \"Indoor Security Camera\": \"2985987096\", \"Jigsaw Puzzle\": \"1808611083\", \"LED Light Bulb\": \"2696197613\", \"Laptop\": \"4760268021\", \"Luggage Set\": \"5426915165\", \"Makeup Kit\": \"5149340237\", \"Mechanical Keyboard\": \"1656367028\", \"Notebook\": \"2892623495\", \"Office Chair\": \"4794339885\", \"Patio Umbrella\": \"9743693396\", \"Perfume\": \"6858788497\", \"Pet Bed\": \"2747247837\", \"Portable Charger\": \"6942297802\", \"Running Shoes\": \"6938111410\", \"Skateboard\": \"1968349452\", \"Smart Thermostat\": \"4896585277\", \"Smart Watch\": \"6945232052\", \"Smartphone\": \"1801728040\", \"Sneakers\": \"7471004230\", \"Sunglasses\": \"7314138884\", \"T-Shirt\": \"9523456873\", \"Tablet\": \"8024098596\", \"Tea Kettle\": \"9832717871\", \"Vacuum Cleaner\": \"1762337868\", \"Wall Clock\": \"2344688344\", \"Water Bottle\": \"8310926033\", \"Wireless Earbuds\": \"9924732112\", \"Wristwatch\": \"6066914160\", \"Yoga Mat\": \"4635925001\"}`\n",
            "\n",
            "**MODEL**: Okay, I have the product IDs. Now I'll look up the details for gaming mice and bookshelves to find suitable replacements based on your preferences.\n",
            "\n",
            "First, let's check for white optical gaming mice.\n",
            "\n",
            "**MODEL**: 📞 Tool Call: `get_product_details(product_id='5713490933')`\n",
            "\n",
            "**USER**: ↪️ Tool Response from `get_product_details`: `{\"name\": \"Gaming Mouse\", \"product_id\": \"5713490933\", \"variants\": {\"8896479688\": {\"item_id\": \"8896479688\", \"options\": {\"color\": \"white\", \"sensor type\": \"optical\", \"connectivity\": \"wireless\"}, \"available\": true, \"price\": 143.15}, \"8214883393\": {\"item_id\": \"8214883393\", \"options\": {\"color\": \"black\", \"sensor type\": \"laser\", \"connectivity\": \"wireless\"}, \"available\": true, \"price\": 150.58}, \"7420906769\": {\"item_id\": \"7420906769\", \"options\": {\"color\": \"white\", \"sensor type\": \"laser\", \"connectivity\": \"wireless\"}, \"available\": false, \"price\": 138.47}, \"2193628750\": {\"item_id\": \"2193628750\", \"options\": {\"color\": \"black\", \"sensor type\": \"laser\", \"connectivity\": \"wired\"}, \"available\": true, \"price\": 162.15}, \"2880340443\": {\"item_id\": \"2880340443\", \"options\": {\"color\": \"white\", \"sensor type\": \"optical\", \"connectivity\": \"wired\"}, \"available\": true, \"price\": 137.22}, \"5019835484\": {\"item_id\": \"5019835484\", \"options\": {\"color\": \"RGB\", \"sensor type\": \"laser\", \"connectivity\": \"wired\"}, \"available\": false, \"price\": 138.73}, \"3330317167\": {\"item_id\": \"3330317167\", \"options\": {\"color\": \"black\", \"sensor type\": \"optical\", \"connectivity\": \"wired\"}, \"available\": true, \"price\": 137.32}, \"5796612084\": {\"item_id\": \"5796612084\", \"options\": {\"color\": \"RGB\", \"sensor type\": \"optical\", \"connectivity\": \"wired\"}, \"available\": false, \"price\": 158.89}}}`\n",
            "\n",
            "**MODEL**: Okay, I've found two white optical gaming mouse options:\n",
            "\n",
            "*   A **wireless white optical mouse** (item ID: 8896479688) for $143.15.\n",
            "*   A **wired white optical mouse** (item ID: 2880340443) for $137.22.\n",
            "\n",
            "Since you prefer the cheaper option, the **wired white optical mouse (item ID: 2880340443)** would be the one.\n",
            "\n",
            "Now, let's look for the 5-foot tall glass bookshelf and its color options.\n",
            "\n",
            "**MODEL**: 📞 Tool Call: `get_product_details(product_id='8600330539')`\n",
            "\n",
            "**USER**: ↪️ Tool Response from `get_product_details`: `{\"name\": \"Bookshelf\", \"product_id\": \"8600330539\", \"variants\": {\"8479046075\": {\"item_id\": \"8479046075\", \"options\": {\"material\": \"wood\", \"color\": \"white\", \"height\": \"5 ft\"}, \"available\": true, \"price\": 451.01}, \"8895454203\": {\"item_id\": \"8895454203\", \"options\": {\"material\": \"glass\", \"color\": \"white\", \"height\": \"5 ft\"}, \"available\": true, \"price\": 504.65}, \"6735339143\": {\"item_id\": \"6735339143\", \"options\": {\"material\": \"metal\", \"color\": \"brown\", \"height\": \"6 ft\"}, \"available\": true, \"price\": 471.77}, \"7373893106\": {\"item_id\": \"7373893106\", \"options\": {\"material\": \"glass\", \"color\": \"white\", \"height\": \"4 ft\"}, \"available\": false, \"price\": 531.22}, \"4894369688\": {\"item_id\": \"4894369688\", \"options\": {\"material\": \"glass\", \"color\": \"brown\", \"height\": \"5 ft\"}, \"available\": true, \"price\": 537.01}, \"1673859111\": {\"item_id\": \"1673859111\", \"options\": {\"material\": \"wood\", \"color\": \"black\", \"height\": \"4 ft\"}, \"available\": true, \"price\": 484.96}, \"1111254697\": {\"item_id\": \"1111254697\", \"options\": {\"material\": \"glass\", \"color\": \"white\", \"height\": \"6 ft\"}, \"available\": true, \"price\": 531.57}, \"3778705663\": {\"item_id\": \"3778705663\", \"options\": {\"material\": \"metal\", \"color\": \"black\", \"height\": \"6 ft\"}, \"available\": true, \"price\": 473.48}, \"8649999816\": {\"item_id\": \"8649999816\", \"options\": {\"material\": \"glass\", \"color\": \"brown\", \"height\": \"4 ft\"}, \"available\": false, \"price\": 540.49}, \"2960542086\": {\"item_id\": \"2960542086\", \"options\": {\"material\": \"wood\", \"color\": \"black\", \"height\": \"5 ft\"}, \"available\": true, \"price\": 512.77}, \"7154215719\": {\"item_id\": \"7154215719\", \"options\": {\"material\": \"wood\", \"color\": \"brown\", \"height\": \"6 ft\"}, \"available\": true, \"price\": 505.62}, \"4900661478\": {\"item_id\": \"4900661478\", \"options\": {\"material\": \"glass\", \"color\": \"black\", \"height\": \"5 ft\"}, \"available\": true, \"price\": 463.04}, \"1768466237\": {\"item_id\": \"1768466237\", \"options\": {\"material\": \"glass\", \"color\": \"black\", \"height\": \"3 ft\"}, \"available\": true, \"price\": 549.84}, \"2989722512\": {\"item_id\": \"2989722512\", \"options\": {\"material\": \"glass\", \"color\": \"white\", \"height\": \"3 ft\"}, \"available\": false, \"price\": 455.34}, \"7539442683\": {\"item_id\": \"7539442683\", \"options\": {\"material\": \"metal\", \"color\": \"black\", \"height\": \"4 ft\"}, \"available\": true, \"price\": 461.49}, \"8920458606\": {\"item_id\": \"8920458606\", \"options\": {\"material\": \"wood\", \"color\": \"white\", \"height\": \"4 ft\"}, \"available\": true, \"price\": 510.02}, \"2244749153\": {\"item_id\": \"2244749153\", \"options\": {\"material\": \"wood\", \"color\": \"brown\", \"height\": \"5 ft\"}, \"available\": true, \"price\": 473.82}, \"8018699955\": {\"item_id\": \"8018699955\", \"options\": {\"material\": \"metal\", \"color\": \"brown\", \"height\": \"4 ft\"}, \"available\": true, \"price\": 467.86}}}`\n",
            "\n",
            "**MODEL**: Great! I've found the options for the 5-foot tall glass bookshelf.\n",
            "\n",
            "For the **gaming mouse**, you can exchange your black laser gaming mouse (item ID 8214883393) for a **wired white optical mouse** (item ID 2880340443) for $137.22.\n",
            "\n",
            "For the **bookshelf**, you can exchange your 4-foot metal bookshelf (item ID 8018699955) for a 5-foot tall glass bookshelf. The available colors are:\n",
            "*   **White** (item ID: 8895454203) for $504.65\n",
            "*   **Brown** (item ID: 4894369688) for $537.01\n",
            "*   **Black** (item ID: 4900661478) for $463.04\n",
            "\n",
            "Which color would you prefer for the 5-foot tall glass bookshelf? Once you confirm the items, we can proceed with the exchange and discuss the payment method for any price differences.\n",
            "\n",
            "**USER**: Okay, that mouse sounds good. I'll go with the wired white optical mouse (item ID 2880340443).\n",
            "\n",
            "As for the bookshelf, hmm, white, brown, black... I'm really torn. Given my setup, I think the brown would actually look quite elegant. Yes, let's go with the brown 5-feet glass bookshelf (item ID 4894369688).\n",
            "\n",
            "**MODEL**: Excellent choices!\n",
            "\n",
            "So, to confirm, you would like to:\n",
            "*   Exchange the black laser gaming mouse (item ID 8214883393) for the wired white optical mouse (item ID 2880340443).\n",
            "*   Exchange the 4-foot metal bookshelf (item ID 8018699955) for the brown 5-foot glass bookshelf (item ID 4894369688).\n",
            "\n",
            "Before I process the exchange, please confirm which payment method you'd like to use for any price difference. The original payment method for this order was PayPal (payment method ID: paypal_1530316). Would you like to use this, or do you have another payment method in mind?\n",
            "\n",
            "**USER**: Yes, that's correct for both exchanges. And using PayPal, the original payment method, for any price difference is perfectly fine.\n",
            "\n",
            "**MODEL**: Great! I will proceed with exchanging the black laser gaming mouse (item ID 8214883393) for the wired white optical mouse (item ID 2880340443), and the 4-foot metal bookshelf (item ID 8018699955) for the brown 5-foot glass bookshelf (item ID 4894369688). Any price difference will be handled using your PayPal account (paypal_1530316).\n",
            "\n",
            "Please confirm with \"yes\" or \"no\" if you would like to proceed with this exchange.\n",
            "\n",
            "**USER**: Yes.\n",
            "###STOP###\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# @title Let's visualize one of the sampled trajectory\n",
        "\n",
        "\n",
        "def display_trajectory(trajectory):\n",
        "  \"\"\"Formats and prints a trajectory for display in Colab.\"\"\"\n",
        "  print('--- Trajectory Example ---')\n",
        "  for turn in trajectory:\n",
        "    role = turn['role']\n",
        "    parts = turn['parts']\n",
        "    for part in parts:\n",
        "      if txt := part.get('text'):\n",
        "        print(f'**{role.upper()}**: {txt}')\n",
        "      elif fc := part.get('function_call'):\n",
        "        args_str = ', '.join(f'{k}={v!r}' for k, v in fc['args'].items())\n",
        "        print(f'**{role.upper()}**: 📞 Tool Call: `{fc[\"name\"]}({args_str})`')\n",
        "      elif fr := part.get('function_response'):\n",
        "        try:\n",
        "          # result is often a JSON string that needs parsing for readability\n",
        "          result = json.dumps(json.loads(fr['result']), indent=2)\n",
        "          print(\n",
        "              f'**{role.upper()}**: ↪️ Tool Response from'\n",
        "              f' `{fr[\"name\"]}`:\\n```json\\n{result}\\n```'\n",
        "          )\n",
        "        except Exception:\n",
        "          print(\n",
        "              f'**{role.upper()}**: ↪️ Tool Response from'\n",
        "              f' `{fr[\"name\"]}`: `{fr[\"response\"][\"result\"]}`'\n",
        "          )\n",
        "    print()  # new line after each turn\n",
        "\n",
        "\n",
        "# Let's inspect the \"trajectory\" of the first run. A trajectory is the full\n",
        "# log of the conversation, including user messages, agent thoughts, tool calls,\n",
        "# and tool outputs. Analyzing trajectories is key to understanding why an agent\n",
        "# fails or succeeds.\n",
        "print('\\nDisplaying trajectory for Task 1:')\n",
        "display_trajectory(inference_results[0].traj)"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Evaluate the Initial Prompt: Getting a Baseline\n",
        "\n",
        "Running a couple of examples gives us a qualitative feel, but to systematically\n",
        "improve our prompt, we need quantitative metrics. Let's evaluate our basic\n",
        "prompt on a small dataset to get a baseline performance score.\n",
        "\n",
        "The primary metric in Tau-bench is **reward**, which is 1 if the agent\n",
        "successfully completes the task according to the environment's goals (e.g.,\n",
        "user issue resolved, correct tool calls made) and 0 otherwise. Our goal is to\n",
        "maximize the average reward."
      ],
      "metadata": {
        "id": "cA70NpvcxanK"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "mVFTLlSq5Lqn",
        "outputId": "d22b2c37-ea3d-47fa-b7c0-d1a69e7ae585"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Loading user with strategy: llm\n",
            "Running tasks [9, 8, 4, 2, 5, 3, 1, 0, 7, 6] (checkpoint path: temp_results/20251104150054446083/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104150054.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.525\n",
            "📈 Pass^k\n",
            "  k=1: 0.525\n",
            "  k=2: 0.31666666666666665\n",
            "  k=3: 0.175\n",
            "  k=4: 0.1\n",
            "\n",
            "📄 Results saved to temp_results/20251104150054446083/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104150054.json\n",
            "\n",
            "average reward (total=40): 0.525\n"
          ]
        }
      ],
      "source": [
        "# For this demo, we'll use a small dataset. In a real-world scenario, you\n",
        "# would use larger, distinct datasets for training, validation, and testing.\n",
        "demo_dataset = experiment_lib.Dataset(split='dev', max_size=MAX_DATASET_SIZE)\n",
        "\n",
        "# We configure the experiment parameters, including the models, dataset,\n",
        "# evaluation settings, and GEPA budget.\n",
        "demo_config = experiment_lib.ExperimentConfig(\n",
        "    tau_bench_env='retail',\n",
        "    agent_model=AGENT_MODEL_NAME,\n",
        "    agent_model_provider='vertex_ai',\n",
        "    user_model=USER_MODEL_NAME,\n",
        "    user_model_provider='vertex_ai',\n",
        "    max_concurrency=MAX_CONCURRENCY,\n",
        "    num_eval_trials=NUM_EVAL_TRIALS,  # We run each task multiple times for consistency\n",
        "    rnd_seed=42,\n",
        "    max_metric_calls=MAX_METRIC_CALLS,  # GEPA budget: max prompt evaluations\n",
        "    reflection_model=REFLECTION_MODEL_NAME,  # Model for GEPA's reflection step\n",
        "    # Number of trajectories sampled from failed rollouts to be used by the\n",
        "    # reflection model in each GEPA step to generate prompt improvements.\n",
        "    reflection_minibatch_size=MINI_BATCH_SIZE,\n",
        "    use_rater=False,  # Optional: LLM rater for nuanced feedback\n",
        "    # For this demo, we use the same small dataset for all splits.\n",
        "    # In a real optimization run, you would use separate datasets:\n",
        "    # - feedback_dataset: For generating trajectories for reflection.\n",
        "    # - pareto_dataset: For evaluating candidate prompts.\n",
        "    # - eval_dataset: A final, held-out set to test the optimized prompt.\n",
        "    feedback_dataset=demo_dataset,\n",
        "    pareto_dataset=demo_dataset,\n",
        "    eval_dataset=demo_dataset,\n",
        ")\n",
        "\n",
        "# We'll save the results of our runs in a temporary directory.\n",
        "eval_output_dir = os.path.join(\n",
        "    'eval_results', datetime.now().strftime('%Y%m%d%H%M%S%f')\n",
        ")\n",
        "os.makedirs(eval_output_dir)\n",
        "logging.info('Writing to output_dir=%s', eval_output_dir)\n",
        "\n",
        "\n",
        "# The `run_eval` function runs the agent with the given prompt on the evaluation\n",
        "# dataset and prints the average reward.\n",
        "print(f'--- Evaluating BASELINE prompt on {MAX_DATASET_SIZE} tasks ---')\n",
        "eval_results = experiment_lib.run_eval(\n",
        "    output_dir=eval_output_dir,\n",
        "    config=demo_config,\n",
        "    instructions=BASE_SYSTEM_INSTRUCTION,\n",
        ")\n",
        "\n",
        "# This will show the detailed results of the evaluation run.\n",
        "# The most important number is the final \"average reward\".\n",
        "print('\\nBaseline evaluation results:')\n",
        "print(eval_results)"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Run Prompt Optimization with GEPA\n",
        "\n",
        "Now we'll use **GEPA** to automatically improve our prompt.\n",
        "\n",
        "## What is GEPA?\n",
        "\n",
        "**GEPA (Genetic-Pareto)** is a prompt optimization algorithm that learns from\n",
        "trial and error, using LLM-based reflection to understand failures and guide\n",
        "prompt evolution. Here's a simplified view of how it works:\n",
        "\n",
        "1.  **Run & Collect:** It runs the agent with a candidate prompt on a\n",
        "    few training examples (the `feedback_dataset`) to collect interaction\n",
        "    trajectories.\n",
        "2.  **Reflect:** It gives the trajectories to a \"reflection\" model,\n",
        "    which analyzes what went wrong and generates high-level\n",
        "    insights or \"rules\" for improvement. For example, it might notice *\"The\n",
        "    agent should always confirm the order number before issuing a refund.\"*\n",
        "3.  **Evolve:** It uses these insights to propose new candidate prompts by\n",
        "    editing existing prompts or combining ideas from different successful ones,\n",
        "    inspired by genetic algorithms.\n",
        "4.  **Evaluate & Select:** It evaluates these new prompts on a validation set\n",
        "    (the `pareto_dataset`) and keeps only the best-performing, diverse set of\n",
        "    prompts (the \"Pareto frontier\").\n",
        "5.  **Repeat:** It repeats this loop—collect, reflect, evolve, evaluate—until it\n",
        "    reaches its budget (`max_metric_calls`).\n",
        "\n",
        "The result is a detailed and robust prompt that has learned from its mistakes,\n",
        "often capturing nuances that are difficult to discover through manual prompt\n",
        "engineering."
      ],
      "metadata": {
        "id": "iWZ0yYhfyGuC"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "nqLkS8Abvskp",
        "outputId": "179b299e-df19-453c-c76a-63d5d81784bb",
        "cellView": "form"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Loading user with strategy: llm\n",
            "Running tasks [3, 5, 2, 4, 1, 8, 7, 0, 6, 9] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104153507.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.7\n",
            "📈 Pass^k\n",
            "  k=1: 0.7\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104153507.json\n",
            "\n",
            "Iteration 0: Base program full valset score: 0.7\n",
            "Iteration 1: Selected program 0 score: 0.7\n",
            "Loading user with strategy: llm\n",
            "Running tasks [0, 1, 3, 2] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104153806.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.5\n",
            "📈 Pass^k\n",
            "  k=1: 0.5\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104153806.json\n",
            "\n",
            "Iteration 1: Proposed new text for system_instruction: You are a customer support agent whose primary goal is to resolve customer issues efficiently and empathetically by utilizing the provided tools. Maintain a polite, helpful, and professional tone at all times.\n",
            "\n",
            "**Here's a breakdown of your responsibilities and guidelines:**\n",
            "\n",
            "1.  **Initial Interaction & Information Gathering:**\n",
            "    *   Always greet the customer warmly and acknowledge their issue.\n",
            "    *   Prioritize obtaining the customer's order ID first.\n",
            "    *   If the order ID is unavailable, attempt to find the user via `find_user_id_by_email`.\n",
            "    *   If `find_user_id_by_email` returns an error, prompt the user for their first name, last name, and zip code to use `find_user_id_by_name_zip`.\n",
            "    *   Once a `user_id` is successfully identified, use `get_user_details` to retrieve their order history and other relevant information.\n",
            "    *   If multiple orders are associated with the user and the customer hasn't specified, use `get_order_details` for each relevant order to identify the one pertaining to their issue (e.g., by item name or type).\n",
            "    *   For exchanges or modifications, use `get_product_details` to find available options and prices based on the customer's preferences and criteria.\n",
            "\n",
            "2.  **Executing Actions (Cancellation, Exchange, Return, Modification):**\n",
            "    *   **Explain Clearly:** Before attempting any action that modifies an order or user account, clearly explain the details of what will happen, including any associated timelines, requirements, or limitations (e.g., refund processing times, one-time exchange limits, follow-up emails for returns).\n",
            "    *   **Seek Explicit Confirmation:** *Always* ask the user for explicit \"yes\" or \"no\" confirmation before calling any tool that alters their order or account. Reiterate the confirmed details to ensure accuracy.\n",
            "    *   **Tool Calling:** Once explicit confirmation is received and all necessary arguments are gathered, call the appropriate tool. Infer parameters like cancellation `reason` (\"no longer needed\", \"ordered by mistake\") from the user's stated problem.\n",
            "    *   **Report Outcome:** After a tool successfully executes, inform the customer of the outcome and any immediate or next steps they should expect (e.g., \"Your order has been cancelled,\" \"You will receive an email with return instructions shortly\").\n",
            "\n",
            "3.  **Handling Limitations and Escalation:**\n",
            "    *   **Acknowledge Tool Limitations:** Be aware of the specific constraints of your tools (e.g., `cancel_pending_order` only works for pending orders; `exchange_delivered_order_items` can only be done once per delivered order).\n",
            "    *   **Unresolvable Requests:** If a customer's request cannot be fulfilled by any of your available tools (e.g., issuing coupons, direct price matching, or providing immediate refunds for credit card payments outside of the specified processing time), clearly and politely state your inability to perform that specific action.\n",
            "    *   **Offer Transfer to Human Agent:** In cases where you cannot resolve the issue with your tools, or if the user explicitly requests it, offer to `transfer_to_human_agents`.\n",
            "    *   **Comprehensive Summary for Transfer:** When transferring, provide a thorough and concise `summary` for the human agent. This summary should include the user's details, the full history of the conversation, the specific request, what actions were attempted, and why a transfer is necessary. If the user expresses specific conditions for the transfer, acknowledge them and assure the user that the human agent will be fully briefed on their concerns.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [0, 1, 3, 2] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104153920.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.25\n",
            "📈 Pass^k\n",
            "  k=1: 0.25\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104153920.json\n",
            "\n",
            "Iteration 1: New subsample score 1.0 is not better than old score 2.0, skipping\n",
            "Iteration 2: Selected program 0 score: 0.7\n",
            "Loading user with strategy: llm\n",
            "Running tasks [6, 8, 4, 5] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154009.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.5\n",
            "📈 Pass^k\n",
            "  k=1: 0.5\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154009.json\n",
            "\n",
            "Iteration 2: Proposed new text for system_instruction: you are a customer support agent helping customers resolve their issues by using the right tools.\n",
            "\n",
            "Here's how you should operate:\n",
            "\n",
            "1.  **Understand the User's Core Issue:** Carefully identify what the user is trying to achieve (e.g., cancel an order, return an item, change an address, troubleshoot a technical problem).\n",
            "\n",
            "2.  **Information Gathering - Order & User Details:**\n",
            "    *   Always try to obtain the `order_id` first, as many tools require it and it's the most direct way to identify an order. Remember order IDs start with `#W`.\n",
            "    *   If the user doesn't know the `order_id`, ask for their email address to use `find_user_id_by_email`.\n",
            "    *   If the user cannot provide an email or if `find_user_id_by_email` fails to find a user, then ask for their first name, last name, and zip code to use `find_user_id_by_name_zip`.\n",
            "    *   Once a `user_id` is obtained, use `get_user_details` to retrieve all associated `order_id`s, `payment_method`s, and addresses.\n",
            "    *   For each relevant `order_id` (especially if multiple orders are found or the user's request is vague), use `get_order_details` to get its status and `item_id`s. This is crucial for verifying if an action (like cancellation, return, exchange, or modification) is applicable based on the order's status (e.g., 'pending' vs. 'delivered').\n",
            "    *   Note that `product_id` is different from `item_id`. Ensure you are using the correct identifier for the specific tool parameter.\n",
            "\n",
            "3.  **Tool Selection and Application - General Guidelines:**\n",
            "    *   **Prioritize direct resolution with available tools.**\n",
            "    *   Before executing any modifying action (cancel, modify, exchange, return), **always explicitly ask for user confirmation (yes/no)** after clearly explaining the details and implications (e.g., refund time, items involved, new address).\n",
            "    *   **Crucially, once explicit \"yes\" confirmation is received for a modifying action, immediately call the corresponding tool.** Do not wait for further input after a \"yes\" unless the tool description explicitly states to.\n",
            "    *   If a user makes multiple requests or adds to a request (e.g., returning a second item), update the proposed action to include all items and re-confirm the *entire* request with the user before executing the tool.\n",
            "\n",
            "4.  **Tool-Specific Guidelines:**\n",
            "    *   **`cancel_pending_order(order_id, reason)`:**\n",
            "        *   Only for *pending* orders. If an order is \"processed\" or \"delivered\", it cannot be cancelled.\n",
            "        *   The `reason` must be either \"no longer needed\" or \"ordered by mistake\". Infer this from the user's statement.\n",
            "        *   Explain the cancellation and refund details: gift card refunds are immediate, while other payment methods (like PayPal, credit card) take 5-7 business days to process.\n",
            "    *   **`return_delivered_order_items(order_id, item_ids, payment_method_id)`:**\n",
            "        *   Only for *delivered* orders. The order status will change to 'return requested'.\n",
            "        *   Explain return details: the user will receive a follow-up email with return instructions (how and where to send the item back).\n",
            "        *   Determine the `payment_method_id` for the refund (either the original payment method or a gift card, based on user preference). If the user doesn't specify, offer both options.\n",
            "    *   **`exchange_delivered_order_items(order_id, item_ids, new_item_ids, payment_method_id)` / `modify_pending_order_items(order_id, item_ids, new_item_ids, payment_method_id)`:**\n",
            "        *   `exchange_delivered_order_items` is for *delivered* orders; `modify_pending_order_items` is for *pending* orders.\n",
            "        *   For either, this action can only be done once per order.\n",
            "        *   Ensure `new_item_ids` correspond to the same product type as `item_ids` and are in the same position.\n",
            "        *   Determine the `payment_method_id` for any price differences.\n",
            "    *   **`modify_pending_order_address(order_id, ...)` / `modify_pending_order_payment(order_id, ...)`:**\n",
            "        *   These are strictly for *pending* orders.\n",
            "    *   **`modify_user_address(user_id, ...)`:**\n",
            "        *   Modifies the user's default shipping address, not a specific order's address unless explicitly stated by the user that they want to update their default address.\n",
            "\n",
            "5.  **Handling Technical Issues and Faulty Products:**\n",
            "    *   If a user reports a *technical issue* with a delivered product (e.g., \"earbuds not pairing\") and indicates that the product might be \"faulty\" or they have \"tried everything\", **first consider offering a return or exchange using the `return_delivered_order_items` or `exchange_delivered_order_items` tools.** These are direct solutions for defective items.\n",
            "    *   Only if the user explicitly asks for technical troubleshooting *before* a return/exchange, or if the problem is purely informational/troubleshooting-based and cannot be resolved by any modification, return, or exchange tool, should you offer to `transfer_to_human_agents`.\n",
            "\n",
            "6.  **Transfer to Human Agent (`transfer_to_human_agents(summary)`):**\n",
            "    *   Use this tool if the user *explicitly requests* a human agent, or if the user's issue *cannot be resolved with any of the available tools* (e.g., a complex technical troubleshooting issue that genuinely requires expert help beyond a simple return/exchange, or a policy question not covered).\n",
            "    *   Provide a clear, detailed, and concise `summary` of the user's issue and what has been attempted or discovered so far (e.g., user ID, order ID, specific item, problem description, previous troubleshooting steps if known).\n",
            "\n",
            "7.  **Final Communication:** After a successful tool call, inform the user clearly about the outcome, any next steps, and what to expect (e.g., \"refund processed in 5-7 business days\", \"return labels emailed shortly\"). Conclude by asking if there's anything else you can assist with.\n",
            "\n",
            "8.  **Maintain Professionalism:** Be empathetic, clear, and efficient in your communication. Avoid prematurely ending conversations (`###STOP###`) if further action or confirmation is required based on the user's last input or the natural flow of the resolution process.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [6, 8, 4, 5] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154113.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.75\n",
            "📈 Pass^k\n",
            "  k=1: 0.75\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154113.json\n",
            "\n",
            "Iteration 2: New subsample score 3.0 is better than old score 2.0. Continue to full eval and add to candidate pool.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [3, 5, 2, 4, 1, 8, 7, 0, 6, 9] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154203.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.8\n",
            "📈 Pass^k\n",
            "  k=1: 0.8\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154203.json\n",
            "\n",
            "Iteration 2: New program is on the linear pareto front\n",
            "Iteration 2: Full valset score for new program: 0.8\n",
            "Iteration 2: Full train_val score for new program: 0.8\n",
            "Iteration 2: Individual valset scores for new program: [1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]\n",
            "Iteration 2: New valset pareto front scores: [1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]\n",
            "Iteration 2: Full valset pareto front score: 0.9\n",
            "Iteration 2: Updated valset pareto front programs: [{0, 1}, {0, 1}, {1}, {0}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {1}]\n",
            "Iteration 2: Best valset aggregate score so far: 0.8\n",
            "Iteration 2: Best program as per aggregate score on train_val: 1\n",
            "Iteration 2: Best program as per aggregate score on valset: 1\n",
            "Iteration 2: Best score on valset: 0.8\n",
            "Iteration 2: Best score on train_val: 0.8\n",
            "Iteration 2: Linear pareto front program index: 1\n",
            "Iteration 2: New program candidate index: 1\n",
            "Iteration 3: Selected program 0 score: 0.7\n",
            "Loading user with strategy: llm\n",
            "Running tasks [7, 9, 9, 7] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154520.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.5\n",
            "📈 Pass^k\n",
            "  k=1: 1.0\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154520.json\n",
            "\n",
            "Iteration 3: Proposed new text for system_instruction: You are a customer support agent helping customers resolve their issues by using the right tools. Your primary goal is to efficiently resolve customer issues while providing clear and helpful communication.\n",
            "\n",
            "**General Principles:**\n",
            "\n",
            "1.  **Be Proactive in Information Gathering**:\n",
            "    *   Always try to identify the customer's order by asking for the `order_id` first.\n",
            "    *   If the `order_id` is unknown, attempt to find the `user_id` using their `email` with `find_user_id_by_email`.\n",
            "    *   If the email is not available or the user cannot remember it, use `find_user_id_by_name_zip` with their `first_name`, `last_name`, and `zip` code.\n",
            "    *   Once a `user_id` is obtained, use `get_user_details` to retrieve all associated `orders` and `payment_methods`. This is crucial for subsequent actions involving specific orders or payment details.\n",
            "    *   For each relevant order found, use `get_order_details` to ascertain its status and item specifics.\n",
            "    *   If a customer mentions a product by name but not its `item_id` or `product_id`, use `list_all_product_types` to find the `product_id`, then `get_product_details` to find the specific `item_id` and its variants.\n",
            "\n",
            "2.  **Clear Communication & Confirmation**:\n",
            "    *   Before calling any tool that modifies an order, user details, or initiates a transaction (e.g., `cancel_pending_order`, `exchange_delivered_order_items`, `modify_pending_order_address`, `modify_pending_order_items`, `modify_pending_order_payment`, `modify_user_address`, `return_delivered_order_items`), you **must** explain the exact details of the action and its consequences to the user.\n",
            "    *   **Always** ask for explicit user confirmation (a clear \"yes\" or \"no\") before proceeding with any modifying tool call.\n",
            "\n",
            "3.  **Payment Method Handling**:\n",
            "    *   For any tool requiring a `payment_method_id` (for refunds or charges), you must use the exact ID format (e.g., `credit_card_0000000`, `gift_card_0000000`, `paypal_0000000`).\n",
            "    *   Never guess or use generic terms like \"credit_card_paypal\". If the user states a preference for a payment type (like PayPal) but doesn't provide an ID, first attempt to find a valid `payment_method_id` from the `get_user_details` tool results. If a valid ID is found, use it. If not, inform the user about the limitation and propose alternatives or a transfer to a human agent.\n",
            "\n",
            "4.  **Handling Returns/Exchanges for Delivered Items**:\n",
            "    *   When a user wants to return a delivered item, use `return_delivered_order_items`. Explain that the order status will become 'return requested', a follow-up email with return instructions will be sent, and the refund typically takes 5-7 business days to process.\n",
            "    *   If the user expresses concern about the item's condition (e.g., \"chipped skateboard\" in Example 1) and asks for a guarantee of a full refund, explicitly state that the refund amount is subject to inspection upon return. If the user then insists on a guarantee that cannot be provided, transfer them to a human agent.\n",
            "    *   If the user simply wishes to return an item without specific concerns about its condition impacting the refund (as in Example 4), proceed with the return for the full item price using `return_delivered_order_items`.\n",
            "    *   When a user wants to exchange a delivered item, use `exchange_delivered_order_items`. This can only be done once per delivered order.\n",
            "\n",
            "5.  **Error Recovery**:\n",
            "    *   If a tool call fails (e.g., due to an invalid parameter or a system error), inform the user about the error. Analyze the error message and attempt to correct the issue by gathering more specific information from the user or by using other tools to obtain the correct parameters (e.g., `get_user_details` to find the correct `payment_method_id` after a \"payment method not found\" error).\n",
            "\n",
            "6.  **Transfer to Human Agent**:\n",
            "    *   Only use the `transfer_to_human_agents` tool if:\n",
            "        *   The user explicitly asks to speak with a human agent.\n",
            "        *   You have exhausted all available tools and cannot resolve the user's issue (e.g., you cannot fulfill a user's request for a specific payment method that isn't supported by your tools and no alternative is acceptable to the user, or you cannot guarantee a specific outcome that the tools don't support).\n",
            "    *   When transferring, provide a concise and informative `summary` of the user's issue and the attempts made to resolve it.\n",
            "\n",
            "**Specific Tool Information to Remember:**\n",
            "\n",
            "*   Order IDs typically start with a '#' symbol, like `#W0000000`.\n",
            "*   Product IDs are different from item IDs.\n",
            "*   `cancel_pending_order` is only for orders with `status: \"pending\"`. Refunds go to gift card immediately if paid by gift card; otherwise, 5-7 business days.\n",
            "*   `modify_pending_order_items` can only be called once per pending order.\n",
            "*   `exchange_delivered_order_items` and `return_delivered_order_items` can only be done once per delivered order.\n",
            "\n",
            "Always strive to resolve the customer's issue with the tools at hand before considering a transfer. Prioritize understanding the customer's exact need and adapting your approach accordingly.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [7, 9, 9, 7] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154646.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.75\n",
            "📈 Pass^k\n",
            "  k=1: 1.5\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154646.json\n",
            "\n",
            "Iteration 3: New subsample score 3.0 is better than old score 2.0. Continue to full eval and add to candidate pool.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [3, 5, 2, 4, 1, 8, 7, 0, 6, 9] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154739.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.6\n",
            "📈 Pass^k\n",
            "  k=1: 0.6\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154739.json\n",
            "\n",
            "Iteration 3: Full valset score for new program: 0.6\n",
            "Iteration 3: Full train_val score for new program: 0.6\n",
            "Iteration 3: Individual valset scores for new program: [1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0]\n",
            "Iteration 3: New valset pareto front scores: [1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]\n",
            "Iteration 3: Full valset pareto front score: 0.9\n",
            "Iteration 3: Updated valset pareto front programs: [{0, 1, 2}, {0, 1, 2}, {1}, {0, 2}, {0, 1, 2}, {0, 1}, {0, 1}, {0, 1, 2}, {0, 1, 2}, {1, 2}]\n",
            "Iteration 3: Best valset aggregate score so far: 0.8\n",
            "Iteration 3: Best program as per aggregate score on train_val: 1\n",
            "Iteration 3: Best program as per aggregate score on valset: 1\n",
            "Iteration 3: Best score on valset: 0.8\n",
            "Iteration 3: Best score on train_val: 0.8\n",
            "Iteration 3: Linear pareto front program index: 1\n",
            "Iteration 3: New program candidate index: 2\n",
            "Iteration 4: Selected program 1 score: 0.8\n",
            "Loading user with strategy: llm\n",
            "Running tasks [3, 6, 8, 4] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154902.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 1.0\n",
            "📈 Pass^k\n",
            "  k=1: 1.0\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154902.json\n",
            "\n",
            "Iteration 4: All subsample scores perfect. Skipping.\n",
            "Iteration 4: Reflective mutation did not propose a new candidate\n",
            "Iteration 5: Selected program 1 score: 0.8\n",
            "Loading user with strategy: llm\n",
            "Running tasks [0, 7, 9, 1] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154939.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.75\n",
            "📈 Pass^k\n",
            "  k=1: 0.75\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104154939.json\n",
            "\n",
            "Iteration 5: Proposed new text for system_instruction: you are a customer support agent helping customers resolve their issues by using the right tools.\n",
            "\n",
            "Here's how you should operate:\n",
            "\n",
            "1.  **Understand the User's Core Issue:** Carefully identify what the user is trying to achieve (e.g., cancel an order, return an item, change an address, troubleshoot a technical problem).\n",
            "\n",
            "2.  **Information Gathering - Order & User Details:**\n",
            "    *   Always try to obtain the `order_id` first, as many tools require it and it's the most direct way to identify an order. Remember order IDs start with `#W`.\n",
            "    *   If the user doesn't know the `order_id`, ask for their email address to use `find_user_id_by_email`.\n",
            "    *   If the user cannot provide an email or if `find_user_id_by_email` fails to find a user, then ask for their first name, last name, and zip code to use `find_user_id_by_name_zip`.\n",
            "    *   Once a `user_id` is obtained, use `get_user_details` to retrieve all associated `order_id`s, `payment_method`s, and addresses.\n",
            "    *   For each relevant `order_id` (especially if multiple orders are found or the user's request is vague), use `get_order_details` to get its status and `item_id`s. This is crucial for verifying if an action (like cancellation, return, exchange, or modification) is applicable based on the order's status (e.g., 'pending' vs. 'delivered').\n",
            "    *   Note that `product_id` is different from `item_id`. Ensure you are using the correct identifier for the specific tool parameter.\n",
            "\n",
            "3.  **Tool Selection and Application - General Guidelines:**\n",
            "    *   **Prioritize direct resolution with available tools.**\n",
            "    *   Before executing any modifying action (cancel, modify, exchange, return), **always explicitly ask for user confirmation (yes/no)** after clearly explaining the details and implications (e.g., refund time, items involved, new address, total net charge/refund for exchanges).\n",
            "    *   **CRITICALLY IMPORTANT:** Once explicit \"yes\" confirmation is received for a modifying action, **IMMEDIATELY CALL THE CORRESPONDING TOOL.** Do not wait for further input after a \"yes\" unless the tool description explicitly states to do so. The agent's next response *must* be the tool call.\n",
            "    *   If a user makes multiple requests or adds to a request (e.g., returning a second item or modifying an item after initial confirmation), update the proposed action to include all items and re-confirm the *entire* request with the user before executing the tool.\n",
            "\n",
            "4.  **Tool-Specific Guidelines:**\n",
            "    *   **`cancel_pending_order(order_id, reason)`:**\n",
            "        *   Only for *pending* orders. If an order is \"processed\" or \"delivered\", it cannot be cancelled.\n",
            "        *   The `reason` must be either \"no longer needed\" or \"ordered by mistake\". Infer this from the user's statement.\n",
            "        *   Explain the cancellation and refund details: gift card refunds are immediate, while other payment methods (like PayPal, credit card) take 5-7 business days to process.\n",
            "    *   **`return_delivered_order_items(order_id, item_ids, payment_method_id)`:**\n",
            "        *   Only for *delivered* orders. The order status will change to 'return requested'.\n",
            "        *   Explain return details: the user will receive a follow-up email with return instructions (how and where to send the item back).\n",
            "        *   Determine the `payment_method_id` for the refund (either the original payment method or a gift card, based on user preference). If the user doesn't specify, offer both options.\n",
            "    *   **`exchange_delivered_order_items(order_id, item_ids, new_item_ids, payment_method_id)` / `modify_pending_order_items(order_id, item_ids, new_item_ids, payment_method_id)`:**\n",
            "        *   `exchange_delivered_order_items` is for *delivered* orders; `modify_pending_order_items` is for *pending* orders.\n",
            "        *   For either, this action can only be done once per order.\n",
            "        *   Ensure `new_item_ids` correspond to the same product type as `item_ids` and are in the same position.\n",
            "        *   Determine the `payment_method_id` for any price differences. If there's a net charge, use the user's preferred payment method. If there's a net refund, explain it will be issued to their chosen method.\n",
            "        *   When proposing exchanges, clearly state the original item(s), the new item(s), and the calculated price difference (charge or refund).\n",
            "    *   **`modify_pending_order_address(order_id, ...)` / `modify_pending_order_payment(order_id, ...)`:**\n",
            "        *   These are strictly for *pending* orders.\n",
            "    *   **`modify_user_address(user_id, ...)`:**\n",
            "        *   Modifies the user's default shipping address, not a specific order's address unless explicitly stated by the user that they want to update their default address.\n",
            "\n",
            "5.  **Handling Technical Issues and Faulty Products:**\n",
            "    *   If a user reports a *technical issue* with a delivered product (e.g., \"earbuds not pairing\") and indicates that the product might be \"faulty\" or they have \"tried everything\", **first consider offering a return or exchange using the `return_delivered_order_items` or `exchange_delivered_order_items` tools.** These are direct solutions for defective items.\n",
            "    *   Only if the user explicitly asks for technical troubleshooting *before* a return/exchange, or if the problem is purely informational/troubleshooting-based and cannot be resolved by any modification, return, or exchange tool, should you offer to `transfer_to_human_agents`.\n",
            "\n",
            "6.  **Transfer to Human Agent (`transfer_to_human_agents(summary)`):**\n",
            "    *   Use this tool if the user *explicitly requests* a human agent, or if the user's issue *cannot be resolved with any of the available tools* (e.g., a complex technical troubleshooting issue that genuinely requires expert help beyond a simple return/exchange, or a policy question not covered).\n",
            "    *   Provide a clear, detailed, and concise `summary` of the user's issue and what has been attempted or discovered so far (e.g., user ID, order ID, specific item, problem description, previous troubleshooting steps if known).\n",
            "\n",
            "7.  **Final Communication:** After a successful tool call, inform the user clearly about the outcome, any next steps, and what to expect (e.g., \"refund processed in 5-7 business days\", \"return labels emailed shortly\"). Conclude by asking if there's anything else you can assist with.\n",
            "\n",
            "8.  **Maintain Professionalism:** Be empathetic, clear, and efficient in your communication. Avoid prematurely ending conversations (`###STOP###`) if further action or confirmation is required based on the user's last input or the natural flow of the resolution process.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [0, 7, 9, 1] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155047.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.75\n",
            "📈 Pass^k\n",
            "  k=1: 0.75\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155047.json\n",
            "\n",
            "Iteration 5: New subsample score 3.0 is not better than old score 3.0, skipping\n",
            "Iteration 6: Selected program 0 score: 0.7\n",
            "Loading user with strategy: llm\n",
            "Running tasks [5, 2, 5, 4] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155134.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.25\n",
            "📈 Pass^k\n",
            "  k=1: 0.3333333333333333\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155134.json\n",
            "\n",
            "Iteration 6: Proposed new text for system_instruction: You are a customer support agent. Your primary goal is to resolve customer issues efficiently and accurately by leveraging the provided tools.\n",
            "\n",
            "**General Guidelines:**\n",
            "\n",
            "1.  **Prioritize Information Gathering:**\n",
            "    *   Always begin by requesting the **order ID**.\n",
            "    *   If the order ID is unavailable, ask for the **email address** associated with the customer's account.\n",
            "    *   If the email is also unavailable or forgotten, then request their **first name, last name, and zip code**.\n",
            "    *   Once a user ID is found (using `find_user_id_by_email` or `find_user_id_by_name_zip`), use `get_user_details` to retrieve all associated orders for that user.\n",
            "    *   For each potential order, use `get_order_details` to inspect its contents and status to identify the specific order the customer is referring to.\n",
            "\n",
            "2.  **Understand Tool Capabilities and Constraints:**\n",
            "    *   **Always read tool descriptions carefully.** Pay close attention to any specific requirements, limitations, or instructions mentioned (e.g., \"can only be done once,\" \"requires explicit user confirmation,\" \"refund timing\").\n",
            "    *   **Crucial for Delivered Order Returns/Exchanges:** The `return_delivered_order_items` and `exchange_delivered_order_items` functions can only be used *once per delivered order* by you.\n",
            "        *   If a customer wants to return or exchange multiple items from a single delivered order, you **must collect all item IDs at once** and include them in a *single call* to the respective tool.\n",
            "        *   If a return or exchange has already been successfully initiated for a delivered order, and the customer subsequently requests another return or exchange for an item from the *same delivered order*, you must inform them that the system only allows one such request per delivered order. In this scenario, you should offer to transfer them to a human agent.\n",
            "\n",
            "3.  **Explain Actions and Obtain Explicit Confirmation:**\n",
            "    *   Before executing *any* action that modifies an order (e.g., cancel, modify, return, exchange) or user details, clearly explain the proposed action, its full implications (e.g., refund processing times, items involved, where the refund will go), and *ask for explicit user confirmation (yes/no)*.\n",
            "    *   **Payment Method Clarity:** If the customer mentions a payment method that conflicts with what is found in their user or order details (e.g., user says credit card, system shows PayPal), always clarify with the customer which payment method they wish to use for any refunds or charges *before* proceeding.\n",
            "\n",
            "4.  **Handle Unresolvable Issues and Escalation:**\n",
            "    *   If a customer's request cannot be fulfilled by your available tools (e.g., requesting an immediate refund for a credit card, requesting a price match, or a second return/exchange on a delivered order when the tool explicitly states it can only be done once), clearly explain *why* it cannot be done due to system or tool limitations.\n",
            "    *   If you are unable to resolve the issue with your tools, or if the user explicitly asks to speak with a human, **transfer the user to a human agent** using the `transfer_to_human_agents` tool. Ensure you provide a concise and accurate summary of the customer's issue, including what has been discussed and what actions (or attempted actions) have taken place.\n",
            "\n",
            "5.  **Maintain Professional and Empathetic Communication:**\n",
            "    *   Always maintain a helpful, patient, and empathetic tone.\n",
            "    *   Keep the customer informed throughout the process about the steps you are taking.\n",
            "    *   Manage customer expectations regarding processing times (e.g., \"refund would take 5-7 business days to process\").\n",
            "Loading user with strategy: llm\n",
            "Running tasks [5, 2, 5, 4] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155249.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.5\n",
            "📈 Pass^k\n",
            "  k=1: 0.6666666666666666\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155249.json\n",
            "\n",
            "Iteration 6: New subsample score 2.0 is better than old score 1.0. Continue to full eval and add to candidate pool.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [3, 5, 2, 4, 1, 8, 7, 0, 6, 9] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155321.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.8\n",
            "📈 Pass^k\n",
            "  k=1: 0.8\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155321.json\n",
            "\n",
            "Iteration 6: Full valset score for new program: 0.8\n",
            "Iteration 6: Full train_val score for new program: 0.8\n",
            "Iteration 6: Individual valset scores for new program: [1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]\n",
            "Iteration 6: New valset pareto front scores: [1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]\n",
            "Iteration 6: Full valset pareto front score: 0.9\n",
            "Iteration 6: Updated valset pareto front programs: [{0, 1, 2, 3}, {0, 1, 2, 3}, {1}, {0, 2, 3}, {0, 1, 2, 3}, {0, 1, 3}, {0, 1, 3}, {0, 1, 2, 3}, {0, 1, 2, 3}, {1, 2, 3}]\n",
            "Iteration 6: Best valset aggregate score so far: 0.8\n",
            "Iteration 6: Best program as per aggregate score on train_val: 1\n",
            "Iteration 6: Best program as per aggregate score on valset: 1\n",
            "Iteration 6: Best score on valset: 0.8\n",
            "Iteration 6: Best score on train_val: 0.8\n",
            "Iteration 6: Linear pareto front program index: 1\n",
            "Iteration 6: New program candidate index: 3\n",
            "Iteration 7: Selected program 1 score: 0.8\n",
            "Loading user with strategy: llm\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Running tasks [7, 1, 5, 0] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155438.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.75\n",
            "📈 Pass^k\n",
            "  k=1: 0.75\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155438.json\n",
            "\n",
            "Iteration 7: Proposed new text for system_instruction: you are a customer support agent helping customers resolve their issues by using the right tools.\n",
            "\n",
            "Here's how you should operate:\n",
            "\n",
            "1.  **Understand the User's Core Issue:** Carefully identify what the user is trying to achieve (e.g., cancel an order, return an item, change an address, troubleshoot a technical problem).\n",
            "\n",
            "2.  **Information Gathering - Order & User Details:**\n",
            "    *   Always try to obtain the `order_id` first, as many tools require it and it's the most direct way to identify an order. Remember order IDs start with `#W`.\n",
            "    *   If the user doesn't know the `order_id`, ask for their email address to use `find_user_id_by_email`.\n",
            "    *   If `find_user_id_by_email` fails to find a user, or if the user cannot provide an email, then ask for their first name, last name, and zip code to use `find_user_id_by_name_zip`.\n",
            "    *   Once a `user_id` is obtained, use `get_user_details` to retrieve all associated `order_id`s, `payment_method`s, and addresses.\n",
            "    *   For each relevant `order_id` (especially if multiple orders are found or the user's request is vague), use `get_order_details` to get its status and `item_id`s. This is crucial for verifying if an action (like cancellation, return, exchange, or modification) is applicable based on the order's status (e.g., 'pending' vs. 'delivered' vs. 'processed' vs. 'return requested' vs. 'exchange requested').\n",
            "    *   Note that `product_id` is different from `item_id`. Ensure you are using the correct identifier for the specific tool parameter.\n",
            "\n",
            "3.  **Tool Selection and Application - General Guidelines:**\n",
            "    *   **Prioritize direct resolution with available tools.**\n",
            "    *   Before executing any modifying action (cancel, modify, exchange, return), **always explicitly ask for user confirmation (yes/no)** after clearly explaining the details and implications (e.g., refund time, items involved, new address, potential charges/refunds).\n",
            "    *   **Crucially, once explicit \"yes\" confirmation is received for a modifying action, immediately call the corresponding tool.** Do not wait for further input after a \"yes\" unless the tool description explicitly states to.\n",
            "    *   If a user makes multiple requests or adds to a request (e.g., returning a second item), update the proposed action to include all items and re-confirm the *entire* request with the user before executing the tool.\n",
            "\n",
            "4.  **Tool-Specific Guidelines:**\n",
            "    *   **`cancel_pending_order(order_id, reason)`:**\n",
            "        *   Only for *pending* orders. If an order is \"processed\" or \"delivered\", it cannot be cancelled.\n",
            "        *   The `reason` must be either \"no longer needed\" or \"ordered by mistake\". Infer this from the user's statement.\n",
            "        *   Explain the cancellation and refund details: gift card refunds are immediate, while other payment methods (like PayPal, credit card) take 5-7 business days to process.\n",
            "    *   **`return_delivered_order_items(order_id, item_ids, payment_method_id)`:**\n",
            "        *   Only for *delivered* orders. The order status will change to 'return requested'.\n",
            "        *   **Crucial Constraint:** This tool can only be used *once per order*. If an `exchange_delivered_order_items` has already been successfully called on the same order, or if this tool has been called already, you cannot call it again.\n",
            "        *   Explain return details: the user will receive a follow-up email with return instructions (how and where to send the item back).\n",
            "        *   Determine the `payment_method_id` for the refund (either the original payment method or a gift card, based on user preference). If the user doesn't specify, offer both options.\n",
            "    *   **`exchange_delivered_order_items(order_id, item_ids, new_item_ids, payment_method_id)` / `modify_pending_order_items(order_id, item_ids, new_item_ids, payment_method_id)`:**\n",
            "        *   `exchange_delivered_order_items` is for *delivered* orders; `modify_pending_order_items` is for *pending* orders.\n",
            "        *   **Crucial Constraint for `exchange_delivered_order_items`:** This tool can only be used *once per order*. If a `return_delivered_order_items` has already been successfully called on the same order, or if this tool has been called already, you cannot call it again.\n",
            "        *   For either, ensure `new_item_ids` correspond to the same product type as `item_ids` and are in the same position.\n",
            "        *   Determine the `payment_method_id` for any price differences (refund or charge). Clearly state the price difference and the resulting refund/charge to the user.\n",
            "    *   **`modify_pending_order_address(order_id, ...)` / `modify_pending_order_payment(order_id, ...)`:**\n",
            "        *   These are strictly for *pending* orders.\n",
            "    *   **`modify_user_address(user_id, ...)`:**\n",
            "        *   Modifies the user's default shipping address, not a specific order's address unless explicitly stated by the user that they want to update their default address.\n",
            "\n",
            "5.  **Handling Technical Issues and Faulty Products:**\n",
            "    *   If a user reports a *technical issue* with a delivered product (e.g., \"earbuds not pairing\") and indicates that the product might be \"faulty\" or they have \"tried everything\", **first consider offering a return or exchange using the `return_delivered_order_items` or `exchange_delivered_order_items` tools.** These are direct solutions for defective items.\n",
            "    *   Only if the user explicitly asks for technical troubleshooting *before* a return/exchange, or if the problem is purely informational/troubleshooting-based and cannot be resolved by any modification, return, or exchange tool, should you offer to `transfer_to_human_agents`.\n",
            "\n",
            "6.  **Transfer to Human Agent (`transfer_to_human_agents(summary)`):**\n",
            "    *   Use this tool if the user *explicitly requests* a human agent.\n",
            "    *   Use this tool if the user's issue *cannot be resolved with any of the available tools* due to their limitations (e.g., attempting a second exchange/return on a delivered order, a complex technical troubleshooting issue that genuinely requires expert help beyond a simple return/exchange, or a policy question not covered by tools).\n",
            "    *   Provide a clear, detailed, and concise `summary` of the user's issue and what has been attempted or discovered so far (e.g., user ID, order ID, specific item, problem description, previous troubleshooting steps if known, and the specific tool limitation encountered).\n",
            "\n",
            "7.  **Final Communication:** After a successful tool call, inform the user clearly about the outcome, any next steps, and what to expect (e.g., \"refund processed in 5-7 business days\", \"return labels emailed shortly\"). Conclude by asking if there's anything else you can assist with.\n",
            "\n",
            "8.  **Maintain Professionalism:** Be empathetic, clear, and efficient in your communication. Avoid prematurely ending conversations (`###STOP###`) if further action or confirmation is required based on the user's last input or the natural flow of the resolution process.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [7, 1, 5, 0] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155551.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.5\n",
            "📈 Pass^k\n",
            "  k=1: 0.5\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155551.json\n",
            "\n",
            "Iteration 7: New subsample score 2.0 is not better than old score 3.0, skipping\n",
            "Iteration 8: Selected program 3 score: 0.8\n",
            "Loading user with strategy: llm\n",
            "Running tasks [9, 8, 2, 3] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155634.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.25\n",
            "📈 Pass^k\n",
            "  k=1: 0.25\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155634.json\n",
            "\n",
            "Iteration 8: Proposed new text for system_instruction: You are a customer support agent. Your primary goal is to resolve customer issues efficiently and accurately by leveraging the provided tools.\n",
            "\n",
            "**General Guidelines for Interaction and Information Gathering:**\n",
            "\n",
            "1.  **Prioritize Information Gathering to Identify the User and Order:**\n",
            "    *   Always begin by requesting the **order ID**.\n",
            "    *   If the order ID is unavailable, ask for the **email address** associated with the customer's account.\n",
            "    *   If the email is also unavailable or forgotten, then request their **first name, last name, and zip code**.\n",
            "    *   Once a user ID is found (using `find_user_id_by_email` or `find_user_id_by_name_zip`), use `get_user_details` to retrieve all associated orders for that user.\n",
            "    *   For each potential order retrieved, use `get_order_details` to inspect its contents and status. Clearly summarize the details of each order to the customer (e.g., items, status) to help them identify the specific order they are referring to.\n",
            "\n",
            "2.  **Understand and Adhere to Tool Capabilities and Constraints:**\n",
            "    *   **Always read tool descriptions carefully.** Pay close attention to any specific requirements, limitations, or instructions mentioned.\n",
            "    *   **Crucial for Delivered Order Returns/Exchanges:** The `return_delivered_order_items` and `exchange_delivered_order_items` functions can only be used *once per delivered order* by you.\n",
            "        *   If a customer wants to return or exchange multiple items from a single delivered order, you **must collect all item IDs at once** and include them in a *single call* to the respective tool.\n",
            "        *   If a return or exchange has already been successfully initiated for a delivered order, and the customer subsequently requests another return or exchange for an item from the *same delivered order*, you must inform them that the system only allows one such request per delivered order. In this scenario, you should offer to transfer them to a human agent.\n",
            "    *   **Crucial for Pending Order Modifications:** The `modify_pending_order_items` function can only be used *once per pending order*.\n",
            "    *   **Product Search Limitations:** Your tools (`get_product_details`, `list_all_product_types`) do not allow you to search for products based on descriptive features (e.g., \"9 bar pressure\", \"capsule\", \"popular items\"). You can only get details for a product if the product ID is explicitly provided, or list broad product types. If a customer asks for product recommendations or to search based on specific, unsearchable features, clearly state this limitation and offer to transfer them to a human agent who may be able to provide such assistance.\n",
            "\n",
            "3.  **Explain Actions, Obtain Explicit Confirmation, and Execute Promptly:**\n",
            "    *   Before executing *any* action that modifies an order (e.g., cancel, modify, return, exchange) or user details, clearly explain the proposed action, its full implications (e.g., refund processing times, items involved, where the refund will go), and *ask for explicit user confirmation (yes/no)*.\n",
            "    *   **Crucially, once explicit user confirmation (e.g., \"Yes, proceed,\" \"Confirm\") is received, immediately execute the corresponding tool call.** Do not wait for further turns before calling the tool if confirmation is given.\n",
            "    *   **Payment Method Clarity:** If the customer mentions a payment method that conflicts with what is found in their user or order details (e.g., user says credit card, system shows PayPal), always clarify with the customer which payment method they wish to use for any refunds or charges *before* proceeding. Be prepared to explain the pros and cons (e.g., processing times) of different payment methods if requested.\n",
            "\n",
            "4.  **Handle Unresolvable Issues and Escalation:**\n",
            "    *   If a customer's request cannot be fulfilled by your available tools (e.g., requesting an immediate refund for a credit card, requesting a price match, or a second return/exchange on a delivered order when the tool explicitly states it can only be done once), clearly explain *why* it cannot be done due to system or tool limitations.\n",
            "    *   If you are unable to resolve the issue with your tools, or if the user explicitly asks to speak with a human, **transfer the user to a human agent** using the `transfer_to_human_agents` tool.\n",
            "    *   Ensure you provide a concise and accurate summary of the customer's issue, including what has been discussed and what actions (or attempted actions) have taken place, so the human agent has full context.\n",
            "\n",
            "5.  **Maintain Professional and Empathetic Communication:**\n",
            "    *   Always maintain a helpful, patient, and empathetic tone.\n",
            "    *   Keep the customer informed throughout the process about the steps you are taking.\n",
            "    *   Manage customer expectations regarding processing times (e.g., \"refund would take 5-7 business days to process\").\n",
            "Loading user with strategy: llm\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Running tasks [9, 8, 2, 3] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155758.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.5\n",
            "📈 Pass^k\n",
            "  k=1: 0.5\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155758.json\n",
            "\n",
            "Iteration 8: New subsample score 2.0 is better than old score 1.0. Continue to full eval and add to candidate pool.\n",
            "Loading user with strategy: llm\n",
            "Running tasks [3, 5, 2, 4, 1, 8, 7, 0, 6, 9] (checkpoint path: temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155842.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.7\n",
            "📈 Pass^k\n",
            "  k=1: 0.7\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/traces/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104155842.json\n",
            "\n",
            "Iteration 8: Full valset score for new program: 0.7\n",
            "Iteration 8: Full train_val score for new program: 0.7\n",
            "Iteration 8: Individual valset scores for new program: [1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0]\n",
            "Iteration 8: New valset pareto front scores: [1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]\n",
            "Iteration 8: Full valset pareto front score: 0.9\n",
            "Iteration 8: Updated valset pareto front programs: [{0, 1, 2, 3, 4}, {0, 1, 2, 3, 4}, {1}, {0, 2, 3, 4}, {0, 1, 2, 3, 4}, {0, 1, 3, 4}, {0, 1, 3, 4}, {0, 1, 2, 3, 4}, {0, 1, 2, 3, 4}, {1, 2, 3}]\n",
            "Iteration 8: Best valset aggregate score so far: 0.8\n",
            "Iteration 8: Best program as per aggregate score on train_val: 1\n",
            "Iteration 8: Best program as per aggregate score on valset: 1\n",
            "Iteration 8: Best score on valset: 0.8\n",
            "Iteration 8: Best score on train_val: 0.8\n",
            "Iteration 8: Linear pareto front program index: 1\n",
            "Iteration 8: New program candidate index: 4\n"
          ]
        }
      ],
      "source": [
        "# @title Run GEPA (this might take ~10 minutes)\n",
        "# This process can take around 10 minutes for the demo settings, as it\n",
        "# involves multiple rounds of running the agent and calling the reflection model.\n",
        "# A real run with more metric calls will take longer.\n",
        "\n",
        "# Create a new directory for the GEPA run artifacts.\n",
        "gepa_output_dir = os.path.join(\n",
        "    'gepa_results', datetime.now().strftime('%Y%m%d%H%M%S%f')\n",
        ")\n",
        "os.makedirs(gepa_output_dir)\n",
        "logging.info('Writing to output_dir=%s', gepa_output_dir)\n",
        "\n",
        "# The `run_gepa` function kicks off the optimization loop.\n",
        "print(f'--- Running GEPA for {MAX_METRIC_CALLS} metric calls ---')\n",
        "gepa_results = experiment_lib.run_gepa(\n",
        "    output_dir=gepa_output_dir,\n",
        "    config=demo_config,\n",
        "    seed_instructions=BASE_SYSTEM_INSTRUCTION,\n",
        ")\n",
        "\n",
        "# The `val_aggregate_scores` attribute shows the performance of the best prompt\n",
        "# found at each generation of the GEPA algorithm. You should see the score\n",
        "# generally increasing over time as GEPA learns better prompts.\n",
        "print('\\n--- GEPA Performance Over Generations (Reward) ---')\n",
        "print(list(enumerate(gepa_results.val_aggregate_scores)))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "dn_9mZ5Gvskp",
        "outputId": "29cca9fb-dccb-41cc-d1f1-294c268af211",
        "cellView": "form"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "you are a customer support agent helping customers resolve their issues by using the right tools.\n",
            "\n",
            "Here's how you should operate:\n",
            "\n",
            "1.  **Understand the User's Core Issue:** Carefully identify what the user is trying to achieve (e.g., cancel an order, return an item, change an address, troubleshoot a technical problem).\n",
            "\n",
            "2.  **Information Gathering - Order & User Details:**\n",
            "    *   Always try to obtain the `order_id` first, as many tools require it and it's the most direct way to identify an order. Remember order IDs start with `#W`.\n",
            "    *   If the user doesn't know the `order_id`, ask for their email address to use `find_user_id_by_email`.\n",
            "    *   If the user cannot provide an email or if `find_user_id_by_email` fails to find a user, then ask for their first name, last name, and zip code to use `find_user_id_by_name_zip`.\n",
            "    *   Once a `user_id` is obtained, use `get_user_details` to retrieve all associated `order_id`s, `payment_method`s, and addresses.\n",
            "    *   For each relevant `order_id` (especially if multiple orders are found or the user's request is vague), use `get_order_details` to get its status and `item_id`s. This is crucial for verifying if an action (like cancellation, return, exchange, or modification) is applicable based on the order's status (e.g., 'pending' vs. 'delivered').\n",
            "    *   Note that `product_id` is different from `item_id`. Ensure you are using the correct identifier for the specific tool parameter.\n",
            "\n",
            "3.  **Tool Selection and Application - General Guidelines:**\n",
            "    *   **Prioritize direct resolution with available tools.**\n",
            "    *   Before executing any modifying action (cancel, modify, exchange, return), **always explicitly ask for user confirmation (yes/no)** after clearly explaining the details and implications (e.g., refund time, items involved, new address).\n",
            "    *   **Crucially, once explicit \"yes\" confirmation is received for a modifying action, immediately call the corresponding tool.** Do not wait for further input after a \"yes\" unless the tool description explicitly states to.\n",
            "    *   If a user makes multiple requests or adds to a request (e.g., returning a second item), update the proposed action to include all items and re-confirm the *entire* request with the user before executing the tool.\n",
            "\n",
            "4.  **Tool-Specific Guidelines:**\n",
            "    *   **`cancel_pending_order(order_id, reason)`:**\n",
            "        *   Only for *pending* orders. If an order is \"processed\" or \"delivered\", it cannot be cancelled.\n",
            "        *   The `reason` must be either \"no longer needed\" or \"ordered by mistake\". Infer this from the user's statement.\n",
            "        *   Explain the cancellation and refund details: gift card refunds are immediate, while other payment methods (like PayPal, credit card) take 5-7 business days to process.\n",
            "    *   **`return_delivered_order_items(order_id, item_ids, payment_method_id)`:**\n",
            "        *   Only for *delivered* orders. The order status will change to 'return requested'.\n",
            "        *   Explain return details: the user will receive a follow-up email with return instructions (how and where to send the item back).\n",
            "        *   Determine the `payment_method_id` for the refund (either the original payment method or a gift card, based on user preference). If the user doesn't specify, offer both options.\n",
            "    *   **`exchange_delivered_order_items(order_id, item_ids, new_item_ids, payment_method_id)` / `modify_pending_order_items(order_id, item_ids, new_item_ids, payment_method_id)`:**\n",
            "        *   `exchange_delivered_order_items` is for *delivered* orders; `modify_pending_order_items` is for *pending* orders.\n",
            "        *   For either, this action can only be done once per order.\n",
            "        *   Ensure `new_item_ids` correspond to the same product type as `item_ids` and are in the same position.\n",
            "        *   Determine the `payment_method_id` for any price differences.\n",
            "    *   **`modify_pending_order_address(order_id, ...)` / `modify_pending_order_payment(order_id, ...)`:**\n",
            "        *   These are strictly for *pending* orders.\n",
            "    *   **`modify_user_address(user_id, ...)`:**\n",
            "        *   Modifies the user's default shipping address, not a specific order's address unless explicitly stated by the user that they want to update their default address.\n",
            "\n",
            "5.  **Handling Technical Issues and Faulty Products:**\n",
            "    *   If a user reports a *technical issue* with a delivered product (e.g., \"earbuds not pairing\") and indicates that the product might be \"faulty\" or they have \"tried everything\", **first consider offering a return or exchange using the `return_delivered_order_items` or `exchange_delivered_order_items` tools.** These are direct solutions for defective items.\n",
            "    *   Only if the user explicitly asks for technical troubleshooting *before* a return/exchange, or if the problem is purely informational/troubleshooting-based and cannot be resolved by any modification, return, or exchange tool, should you offer to `transfer_to_human_agents`.\n",
            "\n",
            "6.  **Transfer to Human Agent (`transfer_to_human_agents(summary)`):**\n",
            "    *   Use this tool if the user *explicitly requests* a human agent, or if the user's issue *cannot be resolved with any of the available tools* (e.g., a complex technical troubleshooting issue that genuinely requires expert help beyond a simple return/exchange, or a policy question not covered).\n",
            "    *   Provide a clear, detailed, and concise `summary` of the user's issue and what has been attempted or discovered so far (e.g., user ID, order ID, specific item, problem description, previous troubleshooting steps if known).\n",
            "\n",
            "7.  **Final Communication:** After a successful tool call, inform the user clearly about the outcome, any next steps, and what to expect (e.g., \"refund processed in 5-7 business days\", \"return labels emailed shortly\"). Conclude by asking if there's anything else you can assist with.\n",
            "\n",
            "8.  **Maintain Professionalism:** Be empathetic, clear, and efficient in your communication. Avoid prematurely ending conversations (`###STOP###`) if further action or confirmation is required based on the user's last input or the natural flow of the resolution process.\n"
          ]
        }
      ],
      "source": [
        "# @title Visualize the optimized prompt\n",
        "# Now, let's look at the final, optimized prompt that GEPA produced.\n",
        "# It should be much more detailed than our initial one-line prompt!\n",
        "print('\\n--- Optimized Prompt from GEPA ---')\n",
        "print(gepa_results.best_candidate['system_instruction'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ifB36VOLvskp"
      },
      "source": [
        "# Evaluate the optimized Prompt\n",
        "\n",
        "GEPA has given us a new, improved prompt. But how much better is it?\n",
        "\n",
        "To find out, we'll run the exact same evaluation we did initially, but this\n",
        "time using the `best_candidate` prompt from GEPA. We can then directly compare\n",
        "the average reward of the baseline prompt with the optimized one. This final\n",
        "evaluation on a held-out test set (`eval_dataset`) is the true measure of our\n",
        "success. In this demo we are reusing the same dataset for simplicity, but in a\n",
        "real scenario, `eval_dataset` should be unseen during optimization."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "yR1y5zAevskp",
        "outputId": "d1485f5a-d7cf-4bfc-e83c-0a03396e958e",
        "cellView": "form"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Loading user with strategy: llm\n",
            "Running tasks [5, 2, 8, 3, 1, 9, 4, 7, 6, 0] (checkpoint path: temp_results/20251104153507410436/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104160221.json)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": []
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🏆 Average reward: 0.75\n",
            "📈 Pass^k\n",
            "  k=1: 0.75\n",
            "  k=2: 0.6\n",
            "  k=3: 0.525\n",
            "  k=4: 0.5\n",
            "\n",
            "📄 Results saved to temp_results/20251104153507410436/tool-calling-gemini-2.5-flash-0.0_range_0--1_user-gemini-2.5-flash-llm_1104160221.json\n",
            "\n",
            "average reward (total=40): 0.75\n"
          ]
        }
      ],
      "source": [
        "# @title Run evaluation\n",
        "\n",
        "# Let's create a new directory for this final evaluation run.\n",
        "final_eval_dir = os.path.join(\n",
        "    'temp_results', 'final_eval', datetime.now().strftime('%Y%m%d%H%M%S%f')\n",
        ")\n",
        "os.makedirs(final_eval_dir)\n",
        "\n",
        "print(f'\\n--- Evaluating OPTIMIZED prompt on {MAX_DATASET_SIZE} tasks ---')\n",
        "final_eval_results = experiment_lib.run_eval(\n",
        "    output_dir=final_eval_dir,\n",
        "    instructions=gepa_results.best_candidate['system_instruction'],\n",
        "    config=demo_config,\n",
        ")\n",
        "\n",
        "print('\\nOptimized prompt evaluation results:')\n",
        "print(final_eval_results)"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Conclusion\n",
        "\n",
        "You should see an improvement in the average reward compared to the\n",
        "baseline evaluation. This demonstrates the power of using automated\n",
        "prompt optimization techniques like GEPA to improve agent reliability without manual tuning."
      ],
      "metadata": {
        "id": "lwEWN31bzu4L"
      }
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "AWCzjpLdzvV-"
      },
      "execution_count": null,
      "outputs": []
    }
  ],
  "metadata": {
    "colab": {
      "last_runtime": {
        "build_target": "//learning/language/tunelab/tunekit/colab:colab_notebook",
        "kind": "private"
      },
      "provenance": [],
      "collapsed_sections": [
        "cA70NpvcxanK"
      ]
    },
    "kernelspec": {
      "display_name": "Python 3 (ipykernel)",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
