Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 39 additions & 14 deletions python/agents/travel-concierge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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:
Expand Down Expand Up @@ -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
```

<details>
<summary>⚡️ Alternative: Using uv</summary>

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.

</details>

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`
Expand Down Expand Up @@ -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
```

Expand All @@ -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
Expand Down Expand Up @@ -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"

...

Expand Down
119 changes: 90 additions & 29 deletions python/agents/travel-concierge/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,98 @@ authors = [
{ name = "Anisha Kaul", email = "[email protected]" },
{ name = "Duncan Renfrow-Symon", email = "[email protected]" },
]
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"
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
9 changes: 9 additions & 0 deletions python/agents/travel-concierge/travel_concierge/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion python/agents/travel-concierge/travel_concierge/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -121,7 +121,7 @@
</FIND_HOTELS>

<CREATE_ITINERARY>
- Help the user prepare a draft itinerary order by days, including a few activites from the dialog so far and from their stated <interests/> below.
- Help the user prepare a draft itinerary order by days, including a few activities from the dialog so far and from their stated <interests/> 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.
Expand Down Expand Up @@ -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>{origin}</origin>
<destination>{destination}</destination>
<start_date>{start_date}</start_date>
Expand All @@ -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`.

<JSON_EXAMPLE>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down