# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from google.adk import Agent from google.adk.agents import sequential_agent from google.adk.tools import tool_context from pydantic import BaseModel SequentialAgent = sequential_agent.SequentialAgent ToolContext = tool_context.ToolContext # 1. Define the data structure for the pizza order. class PizzaOrder(BaseModel): """A data class to hold the details of a pizza order.""" size: str crust: str toppings: list[str] # 2. Define tools for the order intake agent. def get_available_sizes() -> list[str]: """Returns the available pizza sizes.""" return ['small', 'medium', 'large'] def get_available_crusts() -> list[str]: """Returns the available pizza crusts.""" return ['thin', 'thick', 'stuffed'] def get_available_toppings() -> list[str]: """Returns the available pizza toppings.""" return ['pepperoni', 'mushrooms', 'onions', 'sausage', 'bacon', 'pineapple'] # 3. Define the order intake agent. # This agent's job is to interact with the user to fill out a PizzaOrder object. # It uses the output_schema to structure its response as a JSON object that # conforms to the PizzaOrder model. order_intake_agent = Agent( name='order_intake_agent', instruction=( "You are a pizza order intake agent. Your goal is to get the user's" ' pizza order. Use the available tools to find out what sizes, crusts,' ' and toppings are available. Once you have all the information,' ' provide it in the requested format. Your output MUST be a JSON object' ' that conforms to the PizzaOrder schema and nothing else.' ), output_key='pizza_order', output_schema=PizzaOrder, tools=[get_available_sizes, get_available_crusts, get_available_toppings], ) # 4. Define a tool for the order confirmation agent. def calculate_price(tool_context: ToolContext) -> str: """Calculates the price of a pizza order and returns a descriptive string.""" order_dict = tool_context.state.get('pizza_order') if not order_dict: return "I can't find an order to calculate the price for." order = PizzaOrder.model_validate(order_dict) price = 0.0 if order.size == 'small': price += 8.0 elif order.size == 'medium': price += 10.0 elif order.size == 'large': price += 12.0 if order.crust == 'stuffed': price += 2.0 price += len(order.toppings) * 1.5 return f'The total price for your order is ${price:.2f}.' # 5. Define the order confirmation agent. # This agent reads the PizzaOrder object from the session state (placed there by # the order_intake_agent) and confirms the order with the user. order_confirmation_agent = Agent( name='order_confirmation_agent', instruction=( 'Confirm the pizza order with the user. The order is in the state' ' variable `pizza_order`. First, use the `calculate_price` tool to get' ' the price. Then, summarize the order details from {pizza_order} and' ' include the price in your summary. For example: "You ordered a large' ' thin crust pizza with pepperoni and mushrooms. The total price is' ' $15.00."' ), tools=[calculate_price], ) # 6. Define the root agent as a sequential agent. # This agent directs the conversation by running its sub-agents in order. root_agent = SequentialAgent( name='pizza_ordering_agent', sub_agents=[ order_intake_agent, order_confirmation_agent, ], description=( 'This agent is used to order pizza. It will ask the user for their' ' pizza order and then confirm the order with the user.' ), )