{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "4KG8heslwNdJ"
   },
   "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": {},
   "source": [
    "# Vertex AI Agent Engine in Express Mode\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/gemini/agent-engine/agent_engine_express_mode.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://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/agent_engine_express_mode.ipynb\">\n",
    "      <img width=\"32px\" src=\"https://storage.googleapis.com/github-repo/generative-ai/logos/GitHub_Invertocat_Dark.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
    "    </a>\n",
    "  </td>\n",
    "</table>\n",
    "\n",
    "<div style=\"clear: both;\"></div>\n",
    "\n",
    "<p>\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/gemini/agent-engine/agent_engine_express_mode.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/gemini/agent-engine/agent_engine_express_mode.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/gemini/agent-engine/agent_engine_express_mode.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/gemini/agent-engine/agent_engine_express_mode.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/gemini/agent-engine/agent_engine_express_mode.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>\n",
    "</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "oWnJG6W9s9wz"
   },
   "source": [
    "## Set up the environment\n",
    "\n",
    "https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/set-up#sdk-installation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "qn8t6OZZBR2_"
   },
   "outputs": [],
   "source": [
    "%pip install \"google-cloud-aiplatform[agent_engines]\" --force-reinstall --quiet"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "UlZrGQP1kquN"
   },
   "source": [
    "# Sign up for Vertex AI Express mode"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AWXhFk3rkvHt"
   },
   "source": [
    "We can use Vertex Services like Agent Engine and access models without requiring a credit card through Vertex AI Express Mode!\n",
    "\n",
    "Sign up with your google account here: https://cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview to unlock access to certain services and the latest google models models!\n",
    "\n",
    "Vertex Express Mode combined with ADK allow for the creation of advanced agents with customizable tools and a context layer with sessions and memories without any billing!\n",
    "\n",
    "Once you sign up, paste your api key here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Zdr_R5zzkTJX"
   },
   "outputs": [],
   "source": [
    "express_mode_api_key = \"\"  # @param {type:\"string\"}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "h1ey_XgwFpOx"
   },
   "source": [
    "# Develop an Adk agent locally"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KIsEeWOrfpvN"
   },
   "source": [
    "### Step 1: Define a local simple agent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "c09iKPFwhtUL"
   },
   "source": [
    "We will use AdkApp, which is a template to make Adk Agents to create a simple agent that has no tools, just a model. We will be able to converse with it, but it cannot help us with the currency conversion rates.\n",
    "\n",
    "With Vertex AI Express mode, you have access to the latest Google models. For the comprehensive list, see the [Available models and rate limits in express mode](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview#models). We will be using Gemini 2.5 Flash for this example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "J5eBt442ntq4"
   },
   "outputs": [],
   "source": [
    "# Initialize Vertex AI SDK\n",
    "import vertexai\n",
    "from vertexai import agent_engines\n",
    "\n",
    "vertexai.init(api_key=express_mode_api_key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "u6g_sWf8fVpj"
   },
   "outputs": [],
   "source": [
    "model = \"gemini-2.5-flash\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Xdvw9CqwfZeS"
   },
   "outputs": [],
   "source": [
    "from google.adk.agents import Agent\n",
    "from google.adk.apps import App\n",
    "\n",
    "agent = Agent(\n",
    "    model=model,  # Required.\n",
    "    name=\"currency_exchange_agent\",  # Required.\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "r-zZiHpXfdIe"
   },
   "outputs": [],
   "source": [
    "app = agent_engines.AdkApp(\n",
    "    app=App(\n",
    "        name=\"currency_exchange_app\",\n",
    "        root_agent=agent,\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "oClJjHMyfeBG"
   },
   "outputs": [],
   "source": [
    "async for event in app.async_stream_query(\n",
    "    user_id=\"local user\",  # Required\n",
    "    message=\"What is the exchange rate from US dollars to Swedish krona on 2025-09-25?\",\n",
    "):\n",
    "    print(event)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "rauCYC6ufmUe"
   },
   "source": [
    "### Step 2: Define a tool"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vUaZGzUmh5ls"
   },
   "source": [
    "Now that we know we can talk to the agent, lets add a tool. This tool allows the agent to check the exchange rate between two currencies ona given date using the frankfurter app."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "SSUldKSkflJW"
   },
   "outputs": [],
   "source": [
    "def get_exchange_rate(\n",
    "    currency_from: str = \"USD\",\n",
    "    currency_to: str = \"EUR\",\n",
    "    currency_date: str = \"latest\",\n",
    "):\n",
    "    \"\"\"Retrieves the exchange rate between two currencies on a specified date.\"\"\"\n",
    "    import requests\n",
    "\n",
    "    response = requests.get(\n",
    "        f\"https://api.frankfurter.app/{currency_date}\",\n",
    "        params={\"from\": currency_from, \"to\": currency_to},\n",
    "    )\n",
    "    return response.json()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "YwjPSaVof4LZ"
   },
   "source": [
    "To test the function before you use it in your agent, run the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "AsR76YB2f2Od"
   },
   "outputs": [],
   "source": [
    "get_exchange_rate(currency_from=\"USD\", currency_to=\"SEK\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Fsk4g4fYf8ns"
   },
   "source": [
    "### Step 3: Add the tool to your agent and test locally"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0FveK16ZgA6z"
   },
   "source": [
    "You have to associate the tools with the Agent when it is initialized:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "FYhxaPnGf_oA"
   },
   "outputs": [],
   "source": [
    "from google.adk.agents import Agent\n",
    "\n",
    "agent = Agent(\n",
    "    model=model,  # Required.\n",
    "    name=\"currency_exchange_agent\",  # Required.\n",
    "    tools=[get_exchange_rate],  # [new] Optional.\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "H3HTcZFmgHE2"
   },
   "source": [
    "Then, we test locally it like we did before."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "cQXwtqm_gI_1"
   },
   "outputs": [],
   "source": [
    "app = agent_engines.AdkApp(\n",
    "    app=App(\n",
    "        name=\"currency_exchange_app\",\n",
    "        root_agent=agent,\n",
    "    )\n",
    ")\n",
    "async for event in app.async_stream_query(\n",
    "    user_id=\"local user\",\n",
    "    message=\"What is the exchange rate from US dollars to Swedish krona on 2025-09-25?\",\n",
    "):\n",
    "    print(event)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nmyRh5qckedk"
   },
   "source": [
    "# Deploy your Agent with Agent Engine"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6PbMnOLE25NA"
   },
   "source": [
    "### Step 4: Write agent files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ONXGYYIWgZdm"
   },
   "source": [
    "Now that we know our agent will work locally, we can write our code to the local files and deploy it to Google Cloud without cost to Agent Engine with source based deployment! More info can be found at [Deploy an Agent Engine](https://docs.cloud.google.com/agent-builder/agent-engine/deploy#from-source-files)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "bqDemcnqHUG2"
   },
   "outputs": [],
   "source": [
    "!mkdir test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "uJS6VpvKBZAN"
   },
   "outputs": [],
   "source": [
    "%%writefile test/requirements.txt\n",
    "google-cloud-aiplatform[agent_engines,adk]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "l1G9gtSDw8yt"
   },
   "outputs": [],
   "source": [
    "%%writefile test/my_agent.py\n",
    "from google.adk.agents import Agent\n",
    "from vertexai import agent_engines\n",
    "\n",
    "def get_exchange_rate(\n",
    "    currency_from: str = \"USD\",\n",
    "    currency_to: str = \"EUR\",\n",
    "    currency_date: str = \"latest\",\n",
    "):\n",
    "    \"\"\"Retrieves the exchange rate between two currencies on a specified date.\"\"\"\n",
    "    import requests\n",
    "\n",
    "    response = requests.get(\n",
    "        f\"https://api.frankfurter.app/{currency_date}\",\n",
    "        params={\"from\": currency_from, \"to\": currency_to},\n",
    "    )\n",
    "    return response.json()\n",
    "\n",
    "agent = Agent(\n",
    "    model=\"gemini-2.5-flash\",   # Required.\n",
    "    name='currency_exchange_agent',  # Required.\n",
    "    tools=[get_exchange_rate],       # [new] Optional.\n",
    ")\n",
    "\n",
    "adk_app=agent_engines.AdkApp(agent=agent, enable_tracing=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "GnvSbk0-CY5V"
   },
   "outputs": [],
   "source": [
    "# Define Class Methods\n",
    "class_methods = [\n",
    "    {\n",
    "        \"parameters\": {},\n",
    "        \"api_mode\": \"async_stream\",\n",
    "        \"description\": None,\n",
    "        \"name\": \"async_stream_query\",\n",
    "    },\n",
    "    {\n",
    "        \"parameters\": {},\n",
    "        \"api_mode\": \"async\",\n",
    "        \"description\": None,\n",
    "        \"name\": \"async_create_session\",\n",
    "    },\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GeXDv0UIFrC4"
   },
   "source": [
    "### Step 5: Deploy your agent to Agent Engine"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "yFcWb-zEicMr"
   },
   "source": [
    "Deploying your agent to Agent Engine unlocks many Google Cloud services, including the Vertex AI Memory Bank and Session services and a suite of observability, logging, and tracing. All of the conversations with the agent are stored in Vertex AI and can be used to give the agent context for future conversations through long term memories. Visit the Vertex AI documentation to learn more about the [Vertex AI Session service](https://docs.cloud.google.com/agent-builder/agent-engine/sessions/overview) and the [Vertex AI Memory Bank service](https://docs.cloud.google.com/agent-builder/agent-engine/memory-bank/overview)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Yed9Q_OY3RI8"
   },
   "outputs": [],
   "source": [
    "client = vertexai.Client(api_key=express_mode_api_key)\n",
    "\n",
    "remote_agent = client.agent_engines.create(\n",
    "    config={\n",
    "        \"display_name\": \"test agent\",\n",
    "        \"description\": \"test agent\",\n",
    "        \"source_packages\": [\"test\"],\n",
    "        \"entrypoint_module\": \"test.my_agent\",\n",
    "        \"entrypoint_object\": \"adk_app\",\n",
    "        \"requirements_file\": \"test/requirements.txt\",\n",
    "        \"class_methods\": class_methods,\n",
    "        \"agent_framework\": \"google-adk\",\n",
    "    },\n",
    ")\n",
    "remote_agent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "XsJsdx2XFjRN"
   },
   "source": [
    "### Step 6: Talk to your deployed Agent Engine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ZlFJb6KP3g3G"
   },
   "outputs": [],
   "source": [
    "async for item in remote_agent.async_stream_query(\n",
    "    message=\"What is the exchange rate between USD and Korean Won on 2025-09-25?\",\n",
    "    user_id=\"user1\",\n",
    "):\n",
    "    print(item)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "MydwzEUoEXDY"
   },
   "outputs": [],
   "source": [
    "async for item in remote_agent.async_stream_query(\n",
    "    message=\"What can you help me with?\",\n",
    "    user_id=\"user1\",\n",
    "):\n",
    "    print(item)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vFXN8L1PnmT2"
   },
   "source": [
    "# Manage your Agent Engine deployment"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "McPSMcn4mMv1"
   },
   "source": [
    "### Step 7: Talk with your agent through the Agent Engine UI"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "19m_DYgalznc"
   },
   "source": [
    "You can also converse with your deployed agent though the Agent Engine UI in your express mode console. Visit the [Express mode UI](https://console.cloud.google.com/expressmode) and navigate to the Agent Engine menu.\n",
    "\n",
    "![agent-engine-ui](https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/express-mode/agent-engine-ui.png)\n",
    "\n",
    "Once you select your agent, use the Playground to converse with it!\n",
    "\n",
    "![playground](https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/express-mode/playground.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "PDn4ZY03jf1E"
   },
   "source": [
    "### Step 8: View conversation history with Vertex AI Session Service"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "SpqgjdNtitaG"
   },
   "outputs": [],
   "source": [
    "session = list(client.agent_engines.sessions.list(name=remote_agent.api_resource.name))[\n",
    "    0\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "WK1xKnfsj9Wj"
   },
   "outputs": [],
   "source": [
    "list(client.agent_engines.sessions.events.list(name=session.name))"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "express-mode-agent-engine-deployment.ipynb",
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
