diff --git a/python/agents/travel-concierge/README.md b/python/agents/travel-concierge/README.md
index d2ea7a9e1..19facdfc0 100644
--- a/python/agents/travel-concierge/README.md
+++ b/python/agents/travel-concierge/README.md
@@ -91,10 +91,13 @@ Expand on the "Key Components" from above.
### Prerequisites
- Python 3.11+
+- uv
+ - For dependency management and packaging. Please follow the
+ instructions on the official
+ [uv website](https://docs.astral.sh/uv/) for installation.
- Google Cloud Project (for Vertex AI integration)
- API Key for [Google Maps Platform Places API](https://developers.google.com/maps/documentation/places/web-service/get-api-key)
- Google Agent Development Kit 1.0+
-- Poetry: Install Poetry by following the instructions on the official Poetry [website](https://python-poetry.org/docs/)
### Installation
@@ -106,15 +109,10 @@ Expand on the "Key Components" from above.
```
NOTE: From here on, all command-line instructions shall be executed under the directory `travel-concierge/` unless otherwise stated.
-2. Install dependencies using Poetry or pip:
+2. Install dependencies using uv:
- **Note for Linux users:** If you get an error related to `keyring` during the installation, you can disable it by running the following command:
```bash
- poetry config keyring.enabled false
- ```
- This is a one-time setup.
- ```bash
- poetry install
+ uv sync
```
3. Set up Google Cloud credentials:
@@ -153,13 +151,40 @@ Expand on the "Key Components" from above.
gcloud auth application-default login
```
-5. Activate the virtual environment set up by Poetry, run:
+5. Activate the virtual environment set up by uv, run:
```bash
- eval $(poetry env activate)
- (travel-concierge-py3.12) $ # Virtualenv entered
+ source .venv/bin/activate
+ (.venv) $ # Virtualenv entered
```
Repeat this command whenever you have a new shell, before running the commands in this README.
+### Alternative: Using Agent Starter Pack
+
+You can also use the [Agent Starter Pack](https://goo.gle/agent-starter-pack) to create a production-ready version of this agent with additional deployment options:
+
+```bash
+# Create and activate a virtual environment
+python -m venv .venv && source .venv/bin/activate # On Windows: .venv\Scripts\activate
+
+# Install the starter pack and create your project
+pip install --upgrade agent-starter-pack
+agent-starter-pack create my-travel-concierge -a adk@travel-concierge
+```
+
+
+⚡️ Alternative: Using uv
+
+If you have [`uv`](https://github.com/astral-sh/uv) installed, you can create and set up your project with a single command:
+```bash
+uvx agent-starter-pack create my-travel-concierge -a adk@travel-concierge
+```
+This command handles creating the project without needing to pre-install the package into a virtual environment.
+
+
+
+The starter pack will prompt you to select deployment options and provides additional production-ready features including automated CI/CD deployment scripts.
+
+
## Running the Agent
### Using `adk`
@@ -228,7 +253,7 @@ Without specifically optimizing for such usage, this cohort of agents seem to be
To run the illustrative tests and evaluations, install the extra dependencies and run `pytest`:
```
-poetry install --with dev
+uv sync --dev
pytest
```
@@ -249,7 +274,7 @@ pytest eval
To deploy the agent to Vertex AI Agent Engine, run the following command under `travel-concierge`:
```bash
-poetry install --with deployment
+uv sync --group deployment
python deployment/deploy.py --create
```
When this command returns, if it succeeds it will print an AgentEngine resource
@@ -442,7 +467,7 @@ You will get outputs similar to this below:
Are any of these destinations sound interesting? I can provide you with some activities you can do in the destination you selected.
-[user]: "Suggest some acitivities around Baa Atoll"
+[user]: "Suggest some activities around Baa Atoll"
...
diff --git a/python/agents/travel-concierge/pyproject.toml b/python/agents/travel-concierge/pyproject.toml
index 522821d34..4c33200ba 100644
--- a/python/agents/travel-concierge/pyproject.toml
+++ b/python/agents/travel-concierge/pyproject.toml
@@ -9,37 +9,98 @@ authors = [
{ name = "Anisha Kaul", email = "anishasjkaul@google.com" },
{ name = "Duncan Renfrow-Symon", email = "drenfrowsymon@google.com" },
]
-license = "Apache License 2.0"
+license = "Apache-2.0"
readme = "README.md"
requires-python = ">=3.11"
-[tool.poetry.dependencies]
-google-cloud-aiplatform = { extras = [
- "adk",
- "agent-engines",
-], version = "^1.93.0" }
-python = "^3.11"
-pydantic = "^2.10.6"
-python-dotenv = "^1.0.1"
-google-genai = "^1.16.1"
-google-adk = "^1.0.0"
-
-[tool.poetry.group.dev]
-optional = true
-
-[tool.poetry.group.dev.dependencies]
-pytest = "^8.3.5"
-google-adk = { version = "^1.0.0", extras = ["eval"] }
-pytest-asyncio = "^0.26.0"
-
-[tool.poetry.group.deployment]
-optional = true
-
-[tool.poetry.group.deployment.dependencies]
-absl-py = "^2.2.1"
-cloudpickle = "^3.1.1"
-flake8-pyproject = "^1.2.3"
+dependencies = [
+ "google-cloud-aiplatform[adk,agent-engines]>=1.93.0",
+ "google-genai>=1.9.0",
+ "pydantic>=2.10.6",
+ "python-dotenv>=1.0.1",
+ "google-adk>=1.0.0",
+]
+
+[dependency-groups]
+dev = [
+ "pytest>=8.3.2",
+ "pytest-asyncio>=0.23.7",
+ "google-adk[eval]>=1.0.0",
+ "nest-asyncio>=1.6.0",
+ "agent-starter-pack>=0.14.1",
+]
+
+deployment = [
+ "absl-py>=2.2.1",
+]
+
+[project.optional-dependencies]
+
+lint = [
+ "ruff>=0.4.6",
+ "mypy>=1.15.0",
+ "codespell>=2.2.0",
+ "types-pyyaml>=6.0.12.20240917",
+ "types-requests>=2.32.0.20240914",
+]
+
+[tool.ruff]
+line-length = 88
+target-version = "py310"
+
+[tool.ruff.lint]
+select = [
+ "E", # pycodestyle
+ "F", # pyflakes
+ "W", # pycodestyle warnings
+ "I", # isort
+ "C", # flake8-comprehensions
+ "B", # flake8-bugbear
+ "UP", # pyupgrade
+ "RUF", # ruff specific rules
+]
+ignore = ["E501", "C901"] # ignore line too long, too complex
+
+[tool.ruff.lint.isort]
+known-first-party = ["financial_advisor"]
+
+[tool.mypy]
+disallow_untyped_calls = true
+disallow_untyped_defs = true
+disallow_incomplete_defs = true
+no_implicit_optional = true
+check_untyped_defs = true
+disallow_subclassing_any = true
+warn_incomplete_stub = true
+warn_redundant_casts = true
+warn_unused_ignores = true
+warn_unreachable = true
+follow_imports = "silent"
+ignore_missing_imports = true
+explicit_package_bases = true
+disable_error_code = ["misc", "no-untyped-call", "no-any-return"]
+
+exclude = [".venv"]
+
+[tool.codespell]
+ignore-words-list = "rouge,checkin,calle"
+skip = "./locust_env/*,uv.lock,.venv,./frontend,**/*.ipynb,package-lock.json"
+
+[tool.pytest.ini_options]
+pythonpath = "."
+asyncio_default_fixture_loop_scope = "function"
[build-system]
-requires = ["poetry-core>=2.0.0,<3.0.0"]
-build-backend = "poetry.core.masonry.api"
+requires = ["uv_build>=0.8.14,<0.9.0"]
+build-backend = "uv_build"
+
+[tool.uv.build-backend]
+module-root = ""
+
+# This configuration file is used by goo.gle/agent-starter-pack to power remote templating.
+# It defines the template's properties and settings.
+[tool.agent-starter-pack]
+example_question = "I want to book a flight from SFO to LAX"
+
+[tool.agent-starter-pack.settings]
+agent_directory = "travel_concierge"
diff --git a/python/agents/travel-concierge/tests/programmatic_example.py b/python/agents/travel-concierge/tests/programmatic_example.py
index 30658bdd2..7c9180142 100644
--- a/python/agents/travel-concierge/tests/programmatic_example.py
+++ b/python/agents/travel-concierge/tests/programmatic_example.py
@@ -37,7 +37,7 @@
# We are going to run just two turns with the concierge
user_inputs = [
"Inspire me about the Maldives",
- "Show me a few activites around Baa Atoll",
+ "Show me a few activities around Baa Atoll",
]
for user_input in user_inputs:
diff --git a/python/agents/travel-concierge/travel_concierge/__init__.py b/python/agents/travel-concierge/travel_concierge/__init__.py
index c48963cdc..a2572dee8 100644
--- a/python/agents/travel-concierge/travel_concierge/__init__.py
+++ b/python/agents/travel-concierge/travel_concierge/__init__.py
@@ -12,4 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import os
+
+import google.auth
+
+_, project_id = google.auth.default()
+os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
+os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "global")
+os.environ.setdefault("GOOGLE_GENAI_USE_VERTEXAI", "True")
+
from . import agent
diff --git a/python/agents/travel-concierge/travel_concierge/prompt.py b/python/agents/travel-concierge/travel_concierge/prompt.py
index 2bab9b62b..8f2f1e9b2 100644
--- a/python/agents/travel-concierge/travel_concierge/prompt.py
+++ b/python/agents/travel-concierge/travel_concierge/prompt.py
@@ -19,7 +19,7 @@
- You help users to discover their dream vacation, planning for the vacation, book flights and hotels
- You want to gather a minimal information to help the user
- After every tool call, pretend you're showing the result to the user and keep your response limited to a phrase.
-- Please use only the agents and tools to fulfill all user rquest
+- Please use only the agents and tools to fulfill all user request
- If the user asks about general knowledge, vacation inspiration or things to do, transfer to the agent `inspiration_agent`
- If the user asks about finding flight deals, making seat selection, or lodging, transfer to the agent `planning_agent`
- If the user is ready to make the flight booking or process payments, transfer to the agent `booking_agent`
diff --git a/python/agents/travel-concierge/travel_concierge/sub_agents/booking/prompt.py b/python/agents/travel-concierge/travel_concierge/sub_agents/booking/prompt.py
index be22741a4..dde60d5f1 100644
--- a/python/agents/travel-concierge/travel_concierge/sub_agents/booking/prompt.py
+++ b/python/agents/travel-concierge/travel_concierge/sub_agents/booking/prompt.py
@@ -85,7 +85,7 @@
- You are a Payment Gateway simulator for Apple Pay and Google Pay, depending on the user choice follow the scenario highlighted below
- Scenario 1: If the user selects Apple Pay please decline the transaction
- Scenario 2: If the user selects Google Pay please approve the transaction
- - Scenario 3: If the user selects Credit Card plase approve the transaction
+ - Scenario 3: If the user selects Credit Card please approve the transaction
- Once the current transaction is completed, return the final order id.
Current time: {_time}
diff --git a/python/agents/travel-concierge/travel_concierge/sub_agents/in_trip/prompt.py b/python/agents/travel-concierge/travel_concierge/sub_agents/in_trip/prompt.py
index 275e6a297..5bb76dcf5 100644
--- a/python/agents/travel-concierge/travel_concierge/sub_agents/in_trip/prompt.py
+++ b/python/agents/travel-concierge/travel_concierge/sub_agents/in_trip/prompt.py
@@ -34,7 +34,7 @@
- Activities or visits that may be impacted by weather: note date, location and desired weather.
For each identified events, checks their status using tools:s
-- flights delays or cancelations - use `flight_status_check`
+- flights delays or cancellations - use `flight_status_check`
- events that requires booking - use `event_booking_check`
- outdoor activities that may be affected by weather, weather forecasts - use `weather_impact`
diff --git a/python/agents/travel-concierge/travel_concierge/sub_agents/inspiration/prompt.py b/python/agents/travel-concierge/travel_concierge/sub_agents/inspiration/prompt.py
index a12737ad8..cea5705f5 100644
--- a/python/agents/travel-concierge/travel_concierge/sub_agents/inspiration/prompt.py
+++ b/python/agents/travel-concierge/travel_concierge/sub_agents/inspiration/prompt.py
@@ -21,8 +21,8 @@
As part of that, user may ask you for general history or knowledge about a destination, in that scenario, answer briefly in the best of your ability, but focus on the goal by relating your answer back to destinations and activities the user may in turn like.
- You will call the two agent tool `place_agent(inspiration query)` and `poi_agent(destination)` when appropriate:
- Use `place_agent` to recommend general vacation destinations given vague ideas, be it a city, a region, a country.
- - Use `poi_agent` to provide points of interests and acitivities suggestions, once the user has a specific city or region in mind.
- - Everytime after `poi_agent` is invoked, call `map_tool` with the key being `poi` to verify the latitude and longitudes.
+ - Use `poi_agent` to provide points of interests and activities suggestions, once the user has a specific city or region in mind.
+ - Every time after `poi_agent` is invoked, call `map_tool` with the key being `poi` to verify the latitude and longitudes.
- Avoid asking too many questions. When user gives instructions like "inspire me", or "suggest some", just go ahead and call `place_agent`.
- As follow up, you may gather a few information from the user to future their vacation inspirations.
- Once the user selects their destination, then you help them by providing granular insights by being their personal local travel guide
diff --git a/python/agents/travel-concierge/travel_concierge/sub_agents/planning/prompt.py b/python/agents/travel-concierge/travel_concierge/sub_agents/planning/prompt.py
index ec3c76a77..a61edb247 100644
--- a/python/agents/travel-concierge/travel_concierge/sub_agents/planning/prompt.py
+++ b/python/agents/travel-concierge/travel_concierge/sub_agents/planning/prompt.py
@@ -17,7 +17,7 @@
PLANNING_AGENT_INSTR = """
You are a travel planning agent who help users finding best deals for flights, hotels, and constructs full itineraries for their vacation.
You do not handle any bookings. You are helping users with their selections and preferences only.
-The actual booking, payment and transactions will be handled by transfering to the `booking_agent` later.
+The actual booking, payment and transactions will be handled by transferring to the `booking_agent` later.
You support a number of user journeys:
- Just need to find flights,
@@ -94,7 +94,7 @@
- Call the `memorize` tool to store the outbound and inbound flights and seats selections info into the following variables:
- 'outbound_flight_selection' and 'outbound_seat_number'
- 'return_flight_selection' and 'return_seat_number'
- - For flight choise, store the full JSON entries from the `flight_search_agent`'s prior response.
+ - For flight choice, store the full JSON entries from the `flight_search_agent`'s prior response.
- Here's the optimal flow
- search for flights
- choose flight, store choice,
@@ -121,7 +121,7 @@
-- Help the user prepare a draft itinerary order by days, including a few activites from the dialog so far and from their stated below.
+- Help the user prepare a draft itinerary order by days, including a few activities from the dialog so far and from their stated below.
- The itinery should start with traveling to the airport from home. Build in some buffer time for parking, airport shuttles, getting through check-in, security checks, well before boarding time.
- Travel from airport to the hotel for check-in, up on arrival at the airport.
- Then the activities.
@@ -359,7 +359,7 @@
ITINERARY_AGENT_INSTR = """
Given a full itinerary plan provided by the planning agent, generate a JSON object capturing that plan.
-Make sure the activities like getting there from home, going to the hotel to checkin, and coming back home is included in the itinerary:
+Make sure the activities like getting there from home, going to the hotel to check in, and coming back home is included in the itinerary:
{origin}
{destination}
{start_date}
@@ -375,11 +375,11 @@
The JSON object captures the following information:
- The metadata: trip_name, start and end date, origin and destination.
-- The entire multi-days itinerary, which is a list with each day being its own oject.
+- The entire multi-days itinerary, which is a list with each day being its own object.
- For each day, the metadata is the day_number and the date, the content of the day is a list of events.
- Events have different types. By default, every event is a "visit" to somewhere.
- Use 'flight' to indicate traveling to airport to fly.
- - Use 'hotel' to indiciate traveling to the hotel to check-in.
+ - Use 'hotel' to indicate traveling to the hotel to check-in.
- Always use empty strings "" instead of `null`.
diff --git a/python/agents/travel-concierge/travel_concierge/sub_agents/post_trip/prompt.py b/python/agents/travel-concierge/travel_concierge/sub_agents/post_trip/prompt.py
index 9d6301aa5..ca4150d8c 100644
--- a/python/agents/travel-concierge/travel_concierge/sub_agents/post_trip/prompt.py
+++ b/python/agents/travel-concierge/travel_concierge/sub_agents/post_trip/prompt.py
@@ -35,7 +35,7 @@
From user's answers, extract the following types of information and use it in the future:
- Food Dietary preferences
- Travel destination preferences
-- Acitivities preferences
+- Activities preferences
- Business reviews and recommendations
For every individually identified preferences, store their values using the `memorize` tool.
diff --git a/python/agents/travel-concierge/travel_concierge/tools/memory.py b/python/agents/travel-concierge/travel_concierge/tools/memory.py
index bd362d3b7..3cd512417 100644
--- a/python/agents/travel-concierge/travel_concierge/tools/memory.py
+++ b/python/agents/travel-concierge/travel_concierge/tools/memory.py
@@ -113,7 +113,7 @@ def _load_precreated_itinerary(callback_context: CallbackContext):
"""
Sets up the initial state.
Set this as a callback as before_agent_call of the root_agent.
- This gets called before the system instruction is contructed.
+ This gets called before the system instruction is constructed.
Args:
callback_context: The callback context.