{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "pUjCrtd2kA2-"
      },
      "outputs": [],
      "source": [
        "# Copyright 2025 Google LLC\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Qc17fDPckA3A"
      },
      "source": [
        "# Deploy your first agent to Vertex AI Agent Engine\n",
        "\n",
        "<table align=\"left\">\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fagents%2Fagent_engine%2Ftutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/images/branding/productlogos/vertexai/v3/512px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
        "    </a>\n",
        "  </td>\n",
        "</table>\n",
        "\n",
        "<div style=\"clear: both;\"></div>\n",
        "\n",
        "<b>Share to:</b>\n",
        "\n",
        "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/agents/agent_engine/tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
        "</a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eqYrkoiakA3A"
      },
      "source": [
        "| Authors |\n",
        "| --- |\n",
        "| Yee Sian Ng |\n",
        "| Shawn Yang |\n",
        "| [Ivan Nardini](https://github.com/inardini) |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "57dcL7DJkA3A"
      },
      "source": [
        "## Overview\n",
        "\n",
        "This tutorial shows you how to deploy an Agent Development Kit (ADK) agent to Google Cloud's Agent Engine.\n",
        "\n",
        "You'll deploy an AI agent with **Google Search** capability that can retrieve real-time information from the web.\n",
        "\n",
        "You will start with Express Mode (Free & Easy!) using ADK CLI.\n",
        "\n",
        "Then, you will explore the following advanced deployment methods:\n",
        "\n",
        "- **Method 1: Agent object** - Deploy agents for interactive development\n",
        "- **Method 2: Inline Source** - Deploy from source files for CI/CD pipelines"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OC5ixo2HkA3B"
      },
      "source": [
        "## Get started with Express Mode (Start here!)\n",
        "\n",
        "If you are a new Vertex AI user, Express Mode provides:\n",
        "\n",
        "- **Free for 90 days** - No billing account needed\n",
        "- **Quick setup** - Just sign in with your Gmail\n",
        "- **Simple authentication** - Use an API key instead of complex service accounts\n",
        "- **Learn by doing** - Perfect for tutorials, prototypes, and experimentation\n",
        "\n",
        "This is the **recommended starting point** for all developers new to Vertex AI Agent Engine.\n",
        "\n",
        "[Learn more about Express Mode](https://cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "57Ma0J0_kA3B"
      },
      "source": [
        "### Get Your API Key\n",
        "\n",
        "First, let's get you set up with Express Mode and grab your API key. This only takes a couple of minutes!\n",
        "\n",
        "**Here's what you'll do:**\n",
        "\n",
        "1. **Sign up for Express Mode**: Head over to [console.cloud.google.com/expressmode](https://console.cloud.google.com/expressmode) and sign in with your **plain and new** Gmail account.\n",
        "\n",
        "2. **Choose your tier**:\n",
        "   - **New to Google Cloud?** Select the free tier - you get 90 days of free access, no credit card needed!\n",
        "   - **Already have a Google Cloud account?** You can use your existing billing account.\n",
        "\n",
        "3. **Grab your API key**:\n",
        "   - Navigate to **APIs & Services > Credentials**: [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)\n",
        "   - Look for the **API Keys** section\n",
        "   - Copy your **Generative Language API Key**\n",
        "\n",
        "**Important:** Keep your API key safe! Don't share it publicly or commit it to your GitHub repos. Think of it like a password."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kiw5rx6rkA3B"
      },
      "source": [
        "### Save Your API Key\n",
        "\n",
        "Let's securely save your API key in this notebook. Run the cell below and paste your API key when prompted - don't worry, it will be hidden as you type!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "No17Cw5hgx12"
      },
      "source": [
        "### Install required packages\n",
        "\n",
        "Start with installing the required packages.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "tFy3H3aPgx12"
      },
      "outputs": [],
      "source": [
        "%pip install --upgrade --quiet \"google-adk @ git+https://github.com/google/adk-python.git@agent-engine-express-mode\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "WxgFGlMjkA3B"
      },
      "outputs": [],
      "source": [
        "from getpass import getpass\n",
        "\n",
        "# Enter your API key when prompted (it will be hidden)\n",
        "api_key = getpass(\"Enter your Generative Language API Key: \")\n",
        "\n",
        "print(\"✅ API key saved successfully!\")\n",
        "print(\"   You can now deploy your agent using Express Mode\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "E_wU8iGWkA3C"
      },
      "source": [
        "### Create Your First Agent\n",
        "\n",
        "Time to create your agent! We'll use the ADK CLI to set up a new agent project. This creates a directory with all the files you need, including saving your API key so you don't have to enter it again.\n",
        "\n",
        "Run the cell below and when prompted, **choose option 1** to select the Gemini 2.5 Flash model."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9cp_I3dlkA3C"
      },
      "outputs": [],
      "source": [
        "# Create a new ADK agent project\n",
        "!adk create my_agent --api_key={api_key}\n",
        "\n",
        "print(\"\\n✅ Agent project created successfully!\")\n",
        "print(\"   Agent directory: ./my_agent\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CXlE6rLskA3C"
      },
      "source": [
        "### Take a Look at Your Agent\n",
        "\n",
        "Let's see what the ADK CLI created for you. This is a basic agent. "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "fElWYPgQkA3C"
      },
      "outputs": [],
      "source": [
        "# Display the agent code\n",
        "with open(\"my_agent/agent.py\") as f:\n",
        "    print(f.read())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iqPUrECfkA3C"
      },
      "source": [
        "### Deploy your ADK Agent to the Cloud via ADK CLI\n",
        "\n",
        "This is the exciting part! We're going to deploy your agent to Google Cloud's Agent Engine. This means your agent will be running on Google's infrastructure, ready to handle requests 24/7.\n",
        "\n",
        "**What happens during deployment:**\n",
        "- Your agent code gets packaged up\n",
        "- It's uploaded to Agent Engine\n",
        "- Google builds and deploys it on managed infrastructure\n",
        "- You get back a resource name you can use to access your agent\n",
        "\n",
        "This takes about 5-10 minutes, so grab a coffee! ☕\n",
        "\n",
        "**Watch for the ✅ success message** - it will include your agent's resource name. You'll need that in the next step!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OdO0ROWvkA3C"
      },
      "outputs": [],
      "source": [
        "# Deploy the agent using Express Mode with API key\n",
        "!adk deploy agent_engine my_agent"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Qifyf6bjkA3C"
      },
      "source": [
        "### Connect to Your Deployed Agent\n",
        "\n",
        "Great! Your agent is now live on Agent Engine. Let's connect to it so we can start asking questions.\n",
        "\n",
        "**You need to do one thing:** Copy the resource name from the deployment output above (it looks like `projects/123.../locations/us-central1/reasoningEngines/456...`) and paste it into the `agent_resource_name` variable below."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "JMKZcHQqkA3C"
      },
      "outputs": [],
      "source": [
        "import vertexai\n",
        "\n",
        "# Initialize client with API key (Express Mode)\n",
        "client = vertexai.Client(api_key=api_key)\n",
        "\n",
        "# TODO: Replace with your agent's resource name from deployment output\n",
        "agent_resource_name = \"projects/your-project-id/locations/us-central1/reasoningEngines/your-agent-engine-id\"\n",
        "\n",
        "# Get the deployed agent\n",
        "express_agent = client.agent_engines.get(name=agent_resource_name)\n",
        "\n",
        "print(\"✅ Agent retrieved successfully!\")\n",
        "print(f\"  Resource: {express_agent.api_resource.name}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mOmdxtPfkA3C"
      },
      "source": [
        "### Ask Your Agent a Question!\n",
        "\n",
        "Now for the fun part - let's put your agent to work! We're going to ask it about recent AI announcements from Google.\n",
        "\n",
        "Watch how the response streams in real-time. Your agent will use Google Search to find current information and then synthesize it into a helpful answer."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "M0iyJHslkA3C"
      },
      "outputs": [],
      "source": [
        "# Query the agent with streaming responses\n",
        "print(\"🔍 Query: 'What are the latest AI announcements from Google in 2025?'\")\n",
        "print(\"-\" * 70)\n",
        "\n",
        "async for item in express_agent.async_stream_query(\n",
        "    message=\"What are the latest AI announcements from Google in 2025?\",\n",
        "    user_id=\"demo_user_express\",\n",
        "):\n",
        "    # Print the response content\n",
        "    if \"content\" in item and item[\"content\"] and \"parts\" in item[\"content\"]:\n",
        "        for part in item[\"content\"][\"parts\"]:\n",
        "            if \"text\" in part:\n",
        "                print(part[\"text\"], end=\"\", flush=True)\n",
        "\n",
        "print(\"\\n\" + \"-\" * 70)\n",
        "print(\"✅ Query completed successfully!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WRJSB5_wkA3D"
      },
      "source": [
        "## Deployment Methods in Vertex AI Agent Engine\n",
        "\n",
        "So far, you deploy an ADK agent on Agent Engine using the CLI. The methods below are some alternatives for developers who need production-ready deployments with full Google Cloud integration.\n",
        "\n",
        "**Note:** If you're just getting started, we recommend completing Method 1 (Express Mode) first before exploring these alternatives.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KUtvCdpSUdZr"
      },
      "source": [
        "### Method 1: Deploy from Agent Object\n",
        "\n",
        "Use **agent object** deployment for **interactive development in notebook environments** like Colab. You create your agent in memory and deploy it directly.\n",
        "\n",
        "This method requires:\n",
        "1. A Google Cloud project with billing enabled\n",
        "2. Vertex AI API enabled\n",
        "3. Appropriate IAM permissions\n",
        "4. A Cloud Storage bucket for staging"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zdD_3z_BZUpJ"
      },
      "source": [
        "#### Install the Vertex AI SDK\n",
        "\n",
        "For agent object deployment, we need the full Vertex AI SDK. This gives us the ability to deploy in-memory agent objects to production.\n",
        "\n",
        "Run the cell below to install it. Colab will prompt you to restart the runtime after installation."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "dJ9Vf3c1Uoza"
      },
      "outputs": [],
      "source": [
        "!pip install google-cloud-aiplatform[agent_engines] --upgrade --quiet"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "s_N4CcJco8bR"
      },
      "source": [
        "#### Authenticate with Google Cloud\n",
        "\n",
        "If you're running this in Colab, you need to authenticate so the notebook can access your Google Cloud project. Run the cell below and follow the authentication prompts."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "5eiGC3Too_zG"
      },
      "outputs": [],
      "source": [
        "# import sys\n",
        "\n",
        "# if \"google.colab\" in sys.modules:\n",
        "#     from google.colab import auth\n",
        "#     auth.authenticate_user()\n",
        "#     print(\"✅ Authentication successful!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "P6wq_Y22ibJm"
      },
      "source": [
        "#### Configure Your Google Cloud Project\n",
        "\n",
        "Now we need to tell the SDK which Google Cloud project to use. You'll need:\n",
        "- Your **Project ID** (find it in the Google Cloud Console)\n",
        "- A **Cloud Storage bucket** for staging deployment files\n",
        "\n",
        "If you haven't set up a Google Cloud project yet, check out [this guide](https://cloud.google.com/vertex-ai/docs/start/cloud-environment) to get started.\n",
        "\n",
        "Replace the placeholder values below with your actual project ID and bucket name."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "BuKg7RxcibJm"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "\n",
        "import vertexai\n",
        "\n",
        "# TODO: Replace with your project ID and staging bucket\n",
        "PROJECT_ID = \"[your-project-id]\"  # @param {type: \"string\"}\n",
        "LOCATION = \"us-central1\"  # @param {type: \"string\"}\n",
        "STAGING_BUCKET_NAME = \"[your-bucket-name]\"  # @param {type: \"string\"}\n",
        "STAGING_BUCKET = f\"gs://{STAGING_BUCKET_NAME}\"\n",
        "\n",
        "# Auto-detect project if running in Colab\n",
        "if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
        "    PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
        "\n",
        "# Initialize the client with API key\n",
        "client = vertexai.Client(project=PROJECT_ID, location=LOCATION)\n",
        "\n",
        "print(\"✅ Google Cloud environment configured\")\n",
        "print(f\"   Project: {PROJECT_ID}\")\n",
        "print(f\"   Location: {LOCATION}\")\n",
        "print(f\"   Staging Bucket: {STAGING_BUCKET}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xDJj-tSRZ4fw"
      },
      "source": [
        "#### Create Your Agent in Memory\n",
        "\n",
        "With agent object deployment, you create the agent right here in the notebook. Let's build an agent with Google Search capability, just like we did in Express Mode."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "8SwBKKLNaZdE"
      },
      "outputs": [],
      "source": [
        "from google.adk.agents import LlmAgent\n",
        "from google.adk.tools import google_search\n",
        "\n",
        "# Create the agent in memory\n",
        "local_agent = LlmAgent(\n",
        "    name=\"search_agent\",\n",
        "    model=\"gemini-2.5-flash\",\n",
        "    description=\"A production agent that can search the web for current information\",\n",
        "    instruction=\"Use Google Search to find fresh, up-to-date information. Always cite your sources.\",\n",
        "    tools=[google_search],\n",
        ")\n",
        "\n",
        "print(\"✅ Agent created in memory!\")\n",
        "print(f\"   Agent name: {local_agent.name}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3kdQPAHdc1K4"
      },
      "source": [
        "#### Wrap Your Agent in an AdkApp\n",
        "\n",
        "Here's the key step for ADK deployment: we need to wrap our agent in an `AdkApp` object. This wrapper:\n",
        "- Provides the interface that Agent Engine expects\n",
        "- Enables automatic session management with `VertexAiSessionService`\n",
        "- Adds tracing capabilities for debugging\n",
        "\n",
        "When deployed, the `AdkApp` automatically uses managed, persistent session state. For local testing, it uses temporary in-memory sessions."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "MQ8Um3ppc2xn"
      },
      "outputs": [],
      "source": [
        "from vertexai import agent_engines\n",
        "\n",
        "# Wrap the agent in an AdkApp object\n",
        "adk_app = agent_engines.AdkApp(\n",
        "    agent=local_agent,\n",
        "    enable_tracing=True,\n",
        ")\n",
        "\n",
        "print(\"✅ Agent wrapped in AdkApp!\")\n",
        "print(\"   This app is ready for deployment to Agent Engine.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1yCqZTjFaflR"
      },
      "source": [
        "#### Deploy the AdkApp\n",
        "\n",
        "Now let's deploy this `AdkApp` to Agent Engine. The SDK will:\n",
        "1. Package your agent code and the AdkApp wrapper\n",
        "2. Upload it to your Cloud Storage staging bucket\n",
        "3. Build a container with the agent and ADK runtime\n",
        "4. Deploy it to managed infrastructure\n",
        "\n",
        "This takes 5-10 minutes."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ZI-9MIxNah-i"
      },
      "outputs": [],
      "source": [
        "# Deploy the AdkApp to Agent Engine\n",
        "try:\n",
        "    remote_app = client.agent_engines.create(\n",
        "        agent=adk_app,\n",
        "        config=dict(\n",
        "            display_name=\"Search Agent\",\n",
        "            description=\"A production agent that can search the web for current information\",\n",
        "            labels={\"agent_type\": \"search\"},\n",
        "            requirements=[\"google-cloud-aiplatform[adk,agent_engines]\"],\n",
        "            staging_bucket=STAGING_BUCKET,\n",
        "        ),\n",
        "    )\n",
        "\n",
        "    print(\"✅ AdkApp deployed successfully!\")\n",
        "    print(f\"\\nResource name: {remote_app.api_resource.name}\")\n",
        "    print(\"\\nYour agent now has:\")\n",
        "    print(\"  • Managed session state (VertexAiSessionService)\")\n",
        "    print(\"  • Automatic scaling\")\n",
        "    print(\"  • Built-in tracing\")\n",
        "\n",
        "except Exception as e:\n",
        "    print(f\"❌ Deployment failed: {e!s}\")\n",
        "    print(\"\\nPlease check:\")\n",
        "    print(\"  1. Your project ID and location are correct\")\n",
        "    print(\"  2. The Vertex AI API is enabled\")\n",
        "    print(\"  3. You have necessary IAM permissions\")\n",
        "    print(\"  4. Your staging bucket exists and is accessible\")\n",
        "    raise"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xklT1oBskhsR"
      },
      "source": [
        "#### Test the Deployed AdkApp\n",
        "\n",
        "Let's query the agent using the session we just created. Notice how we pass the `session_id` - this enables the agent to maintain context across multiple turns."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mohzPTk9kowc"
      },
      "source": [
        "##### Create a Session\n",
        "\n",
        "Before querying the deployed agent, we need to create a session. Sessions maintain conversation history and state across multiple queries."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OMqhkB_sah2c"
      },
      "outputs": [],
      "source": [
        "# Create a session for this user\n",
        "remote_session = await remote_app.async_create_session(user_id=\"demo_user_adk\")\n",
        "\n",
        "print(\"✅ Session created!\")\n",
        "print(f\"   Session ID: {remote_session['id']}\")\n",
        "print(f\"   User ID: {remote_session['userId']}\")\n",
        "print(f\"   App Name: {remote_session['appName']}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mSls1snKpzYA"
      },
      "source": [
        "##### Test the Deployed AdkApp\n",
        "\n",
        "Let's query the agent using the session we just created. Notice how we pass the `session_id` - this enables the agent to maintain context across multiple turns."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "3gClVJTjacPl"
      },
      "outputs": [],
      "source": [
        "# Query the agent with streaming responses\n",
        "print(\"🔍 Query: 'What are the top tech trends in 2025?'\")\n",
        "print(\"=\" * 70)\n",
        "\n",
        "async for event in remote_app.async_stream_query(\n",
        "    user_id=\"demo_user_adk\",\n",
        "    session_id=remote_session[\"id\"],\n",
        "    message=\"What are the top tech trends in 2025?\",\n",
        "):\n",
        "    # Print the response content\n",
        "    if event.get(\"content\", {}).get(\"parts\"):\n",
        "        for part in event[\"content\"][\"parts\"]:\n",
        "            if \"text\" in part:\n",
        "                print(part[\"text\"], end=\"\", flush=True)\n",
        "\n",
        "print(\"✅ Query completed successfully!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6GBZNVM_Ttdt"
      },
      "source": [
        "### Method 2: Inline Source Deployment\n",
        "\n",
        "Use **Inline Source** deployment when you need:\n",
        "\n",
        "- **CI/CD pipelines** - Automated, file-based deployments\n",
        "- **Version control** - Deploy from local source files\n",
        "- **Reproducible builds** - No serialization, just source code\n",
        "- **Infrastructure as Code** - Works with Terraform and other IaC tools\n",
        "\n",
        "This method is perfect for **automated workflows and production pipelines**. You deploy directly from source code files without needing to create an agent object in memory or a Cloud Storage bucket.\n",
        "\n",
        "This method requires:\n",
        "1. A Google Cloud project with billing enabled\n",
        "2. Vertex AI API enabled\n",
        "3. Appropriate IAM permissions\n",
        "\n",
        "**Note:** Unlike ADK App deployment, inline source **does not require a Cloud Storage bucket**!\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8KhB749GsaNn"
      },
      "source": [
        "#### Install the Vertex AI SDK\n",
        "\n",
        "For agent object deployment, we need the full Vertex AI SDK. This gives us the ability to deploy in-memory agent objects to production.\n",
        "\n",
        "Run the cell below to install it. Colab will prompt you to restart the runtime after installation."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QlwSZ2EHsaNr"
      },
      "outputs": [],
      "source": [
        "%pip3 install \"google-cloud-aiplatform[agent_engines] @ git+https://github.com/googleapis/python-aiplatform.git@copybara_817827304\" --upgrade --quiet"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wbQ2bL8lkA3D"
      },
      "source": [
        "#### Download a Sample Agent\n",
        "\n",
        "For this example, we'll download a pre-built agent from GitHub.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "KjbfwhAvkA3D"
      },
      "outputs": [],
      "source": [
        "# Download the agent code from GitHub\n",
        "!rm -rf agent_package\n",
        "!git clone https://github.com/shawn-yang-google/adk-samples.git --quiet\n",
        "!cp -a  adk-samples/python/agents/academic-research/. ./\n",
        "!rm -rf adk-samples\n",
        "\n",
        "print(\"✅ Agent code downloaded successfully\")\n",
        "print(\"\\nAgent package structure:\")\n",
        "!ls -la agent_package/"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eAUSaqA1kA3D"
      },
      "source": [
        "#### Check Out the Agent Code\n",
        "\n",
        "Let's take a quick look at the agent we just downloaded. It's structured similarly to the one we created in Method 1."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9aq91rF4kA3D"
      },
      "outputs": [],
      "source": [
        "# Display the agent code\n",
        "with open(\"academic_research/agent.py\") as f:\n",
        "    print(f.read())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "QHx4G-gpkA3D"
      },
      "source": [
        "#### Set Up the Deployment Configuration\n",
        "\n",
        "With Inline Source deployment, we have more control over how the agent is deployed. We need to specify:\n",
        "\n",
        "- **source_packages**: Which local directories contain our agent code\n",
        "- **entrypoint_module**: The Python module with our agent (in this case, `agent_package.agent`)\n",
        "- **entrypoint_object**: The name of our agent variable (can be `root_agent` or `AdkApp`)\n",
        "- **class_methods**: Which methods should be available on the deployed agent\n",
        "\n",
        "This might look like a lot, but it gives us flexibility for production deployments!"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "13TL2NGRkA3D"
      },
      "outputs": [],
      "source": [
        "import vertexai\n",
        "\n",
        "# Initialize Vertex AI client with Google Cloud project\n",
        "client = vertexai.Client(\n",
        "    project=PROJECT_ID,\n",
        "    location=LOCATION,\n",
        ")\n",
        "\n",
        "# Define the async methods available on the deployed agent\n",
        "class_methods = [\n",
        "    {\n",
        "        \"parameters\": {},\n",
        "        \"api_mode\": \"async_stream\",\n",
        "        \"description\": \"Stream responses from the agent\",\n",
        "        \"name\": \"async_stream_query\",\n",
        "    },\n",
        "    {\n",
        "        \"parameters\": {},\n",
        "        \"api_mode\": \"async\",\n",
        "        \"description\": \"Create a new session\",\n",
        "        \"name\": \"async_create_session\",\n",
        "    },\n",
        "]\n",
        "\n",
        "print(\"✅ Deployment configuration prepared\")\n",
        "print(f\"   Available methods: {[m['name'] for m in class_methods]}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wt1m17kDkA3D"
      },
      "source": [
        "#### Deploy Your Agent with Inline Source\n",
        "\n",
        "Here's where it all comes together! This deployment is a bit more complex than Express Mode:\n",
        "\n",
        "1. Your code gets packaged into a tarfile (in memory)\n",
        "2. It's uploaded to your Cloud Storage staging bucket\n",
        "3. Agent Engine builds a container image with your code\n",
        "4. The container is deployed to managed infrastructure\n",
        "\n",
        "This takes 5-10 minutes. The cell below includes error handling to help you troubleshoot if something goes wrong."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "8McdNSHKkA3D"
      },
      "outputs": [],
      "source": [
        "try:\n",
        "    inline_agent = client.agent_engines.create(\n",
        "        config={\n",
        "            \"display_name\": \"Academic Research Agent\",\n",
        "            \"description\": \"An agent to answer questions about academic research\",\n",
        "            \"labels\": {\"agent_type\": \"academic_research\"},\n",
        "            \"source_packages\": [\"academic_research\", \"deployment\", \"requirements.txt\"],\n",
        "            \"entrypoint_module\": \"deployment.deploy\",\n",
        "            \"entrypoint_object\": \"adk_app\",\n",
        "            \"class_methods\": class_methods,\n",
        "        },\n",
        "    )\n",
        "\n",
        "    print(\"\\n\" + \"=\" * 70)\n",
        "    print(\"✅ Agent deployed successfully with inline source!\")\n",
        "    print(\"=\" * 70)\n",
        "    print(f\"\\nResource name: {inline_agent.api_resource.name}\")\n",
        "    print(\"\\nYou can now query this agent using the Python SDK.\")\n",
        "\n",
        "except Exception as e:\n",
        "    print(f\"❌ Deployment failed: {e!s}\")\n",
        "    print(\"\\nPlease check:\")\n",
        "    print(\"  1. Your project ID and location are correct\")\n",
        "    print(\"  2. The Vertex AI API is enabled\")\n",
        "    print(\"  3. You have necessary IAM permissions\")\n",
        "    print(\"  4. Your staging bucket exists and is accessible\")\n",
        "    raise"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6eUw2lA0kA3E"
      },
      "source": [
        "#### Test Your Agent\n",
        "\n",
        "Let's make sure everything works! We'll ask the agent about quantum computing - a topic that requires current information from the web."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "RksdPSa1kA3E"
      },
      "outputs": [],
      "source": [
        "# Query the agent with streaming responses\n",
        "print(\"🔍 Query: 'What are the latest developments in quantum computing?'\")\n",
        "print(\"=\" * 70)\n",
        "\n",
        "async for item in inline_agent.async_stream_query(\n",
        "    message=\"What are the latest developments in quantum computing?\",\n",
        "    user_id=\"demo_user_inline\",\n",
        "):\n",
        "    # Print the response content\n",
        "    if \"content\" in item and item[\"content\"] and \"parts\" in item[\"content\"]:\n",
        "        for part in item[\"content\"][\"parts\"]:\n",
        "            if \"text\" in part:\n",
        "                print(part[\"text\"], end=\"\", flush=True)\n",
        "\n",
        "print(\"\\n\" + \"=\" * 70)\n",
        "print(\"✅ Query completed successfully!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AyXLKPbokA3H"
      },
      "source": [
        "## Cleaning up\n",
        "\n",
        "When you're done experimenting, it's a good idea to delete your deployed agents to avoid unexpected charges. This is especially important for the Inline Source deployment (Method 2), which uses billable Google Cloud resources.\n",
        "\n",
        "**For Express Mode users:** Remember, you have 90 days of free usage, but it's still good practice to clean up when you're done."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wmjI09Wlx_8V"
      },
      "source": [
        "### Delete your Express Mode deployed agent\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "qfN7gMAskA3H"
      },
      "outputs": [],
      "source": [
        "# # Uncomment to delete the Express Mode deployed agent\n",
        "# try:\n",
        "#     express_agent.delete(force=True)\n",
        "#     print(f\"✅ Agent {express_agent.api_resource.name} has been deleted.\")\n",
        "# except Exception as e:\n",
        "#     print(f\"⚠️  Could not delete agent: {str(e)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "XUoSKo9YkA3H"
      },
      "source": [
        "### Delete Your Inline Source Agent\n",
        "\n",
        "If you deployed an agent using Method 2, uncomment and run the cell below to delete it."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "b_OnCAB5kA3H"
      },
      "outputs": [],
      "source": [
        "# # Uncomment to delete the Inline Source deployed agent\n",
        "# try:\n",
        "#     inline_agent.delete(force=True)\n",
        "#     print(f\"✅ Agent {inline_agent.api_resource.name} has been deleted.\")\n",
        "# except Exception as e:\n",
        "#     print(f\"⚠️  Could not delete agent: {str(e)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "08SAaWJMkA3H"
      },
      "source": [
        "## Next Steps\n",
        "\n",
        "Congratulations! You now know how to deploy ADK agents to Agent Engine:\n",
        "\n",
        "1. **Started with Express Mode** - The free, easy way to deploy agents with just an API key\n",
        "2. **Explored alternatives** - Learned about Inline Source deployment\n",
        "3. Created an ADK agent with Google Search capability\n",
        "4. Deployed and tested your agent with streaming queries\n",
        "5. Learned how to clean up resources\n",
        "\n",
        "As next steps, you can try to:\n",
        "\n",
        "- Add custom tools to your agents\n",
        "- Build multi-agent systems\n",
        "- Create conversational workflows\n",
        "- Test different prompting strategies\n",
        "\n",
        "And when you are ready you can **upgrade from Express Mode** to get full Google Cloud access:\n",
        "\n",
        "1. Go to [console.cloud.google.com/billing](https://console.cloud.google.com/billing)\n",
        "2. Click \"Access all Google Cloud\" to upgrade\n",
        "3. Transition to Inline Source deployment\n",
        "4. Configure IAM, monitoring, and production features\n",
        "\n",
        "Below some resources:\n",
        "\n",
        "- [Agent Engine Documentation](https://cloud.google.com/vertex-ai/docs/agent-engine)\n",
        "- [ADK Documentation](https://google.github.io/adk-docs/)\n",
        "- [ADK CLI Reference](https://google.github.io/adk-docs/cli/)\n",
        "- [ADK Samples Repository](https://github.com/google/adk-samples)"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "tutorial_deploy_your_first_adk_agent_on_agent_engine.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
