From a58cc3d882e59358553e8ea16d166b1ab6d3aa71 Mon Sep 17 00:00:00 2001 From: Hangfei Lin Date: Mon, 30 Jun 2025 09:20:21 -0700 Subject: [PATCH] chore: Create an example for multi agent live streaming This example include multi agents: - Root agent. - Sub agent for Rolling Dice. - Sub agent for checking primes. Added README.md to demonstrate how to use it. PiperOrigin-RevId: 777599625 --- .../__init__.py | 0 .../live_bidi_streaming_multi_agent/agent.py | 129 ++++++++++++++++++ .../live_bidi_streaming_multi_agent/readme.md | 43 ++++++ .../__init__.py | 15 ++ .../agent.py | 0 .../readme.md | 0 6 files changed, 187 insertions(+) rename contributing/samples/{live_bidi_streaming_agent => live_bidi_streaming_multi_agent}/__init__.py (100%) mode change 100755 => 100644 create mode 100644 contributing/samples/live_bidi_streaming_multi_agent/agent.py create mode 100644 contributing/samples/live_bidi_streaming_multi_agent/readme.md create mode 100755 contributing/samples/live_bidi_streaming_single_agent/__init__.py rename contributing/samples/{live_bidi_streaming_agent => live_bidi_streaming_single_agent}/agent.py (100%) rename contributing/samples/{live_bidi_streaming_agent => live_bidi_streaming_single_agent}/readme.md (100%) diff --git a/contributing/samples/live_bidi_streaming_agent/__init__.py b/contributing/samples/live_bidi_streaming_multi_agent/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from contributing/samples/live_bidi_streaming_agent/__init__.py rename to contributing/samples/live_bidi_streaming_multi_agent/__init__.py diff --git a/contributing/samples/live_bidi_streaming_multi_agent/agent.py b/contributing/samples/live_bidi_streaming_multi_agent/agent.py new file mode 100644 index 00000000..09b08e32 --- /dev/null +++ b/contributing/samples/live_bidi_streaming_multi_agent/agent.py @@ -0,0 +1,129 @@ +# Copyright 2025 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. + +import random + +from google.adk.agents import Agent +from google.adk.examples.example import Example +from google.adk.tools.example_tool import ExampleTool +from google.genai import types + + +# --- Roll Die Sub-Agent --- +def roll_die(sides: int) -> int: + """Roll a die and return the rolled result.""" + return random.randint(1, sides) + + +roll_agent = Agent( + name="roll_agent", + description="Handles rolling dice of different sizes.", + instruction=""" + You are responsible for rolling dice based on the user's request. + When asked to roll a die, you must call the roll_die tool with the number of sides as an integer. + """, + tools=[roll_die], + generate_content_config=types.GenerateContentConfig( + safety_settings=[ + types.SafetySetting( # avoid false alarm about rolling dice. + category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, + threshold=types.HarmBlockThreshold.OFF, + ), + ] + ), +) + + +# --- Prime Check Sub-Agent --- +def check_prime(nums: list[int]) -> str: + """Check if a given list of numbers are prime.""" + primes = set() + for number in nums: + number = int(number) + if number <= 1: + continue + is_prime = True + for i in range(2, int(number**0.5) + 1): + if number % i == 0: + is_prime = False + break + if is_prime: + primes.add(number) + return ( + "No prime numbers found." + if not primes + else f"{', '.join(str(num) for num in primes)} are prime numbers." + ) + + +prime_agent = Agent( + name="prime_agent", + description="Handles checking if numbers are prime.", + instruction=""" + You are responsible for checking whether numbers are prime. + When asked to check primes, you must call the check_prime tool with a list of integers. + Never attempt to determine prime numbers manually. + Return the prime number results to the root agent. + """, + tools=[check_prime], + generate_content_config=types.GenerateContentConfig( + safety_settings=[ + types.SafetySetting( # avoid false alarm about rolling dice. + category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, + threshold=types.HarmBlockThreshold.OFF, + ), + ] + ), +) + + +def get_current_weather(location: str): + """ + Returns the current weather. + """ + if location == "New York": + return "Sunny" + else: + return "Raining" + + +root_agent = Agent( + # find supported models here: https://google.github.io/adk-docs/get-started/streaming/quickstart-streaming/ + # model='gemini-live-2.5-flash-preview-native-audio', # for Vertex project + model="gemini-live-2.5-flash-preview", # for AI studio key + name="root_agent", + instruction=""" + You are a helpful assistant that can check time, roll dice and check if numbers are prime. + You can check time on your own. + You delegate rolling dice tasks to the roll_agent and prime checking tasks to the prime_agent. + Follow these steps: + 1. If the user asks to roll a die, delegate to the roll_agent. + 2. If the user asks to check primes, delegate to the prime_agent. + 3. If the user asks to roll a die and then check if the result is prime, call roll_agent first, then pass the result to prime_agent. + Always clarify the results before proceeding. + """, + global_instruction=( + "You are DicePrimeBot, ready to roll dice and check prime numbers." + ), + sub_agents=[roll_agent, prime_agent], + tools=[get_current_weather], + generate_content_config=types.GenerateContentConfig( + safety_settings=[ + types.SafetySetting( # avoid false alarm about rolling dice. + category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, + threshold=types.HarmBlockThreshold.OFF, + ), + ] + ), +) diff --git a/contributing/samples/live_bidi_streaming_multi_agent/readme.md b/contributing/samples/live_bidi_streaming_multi_agent/readme.md new file mode 100644 index 00000000..27c93b10 --- /dev/null +++ b/contributing/samples/live_bidi_streaming_multi_agent/readme.md @@ -0,0 +1,43 @@ +# Simplistic Live (Bidi-Streaming) Multi-Agent +This project provides a basic example of a live, bidirectional streaming multi-agent +designed for testing and experimentation. + +You can see full documentation [here](https://google.github.io/adk-docs/streaming/). + +## Getting Started + +Follow these steps to get the agent up and running: + +1. **Start the ADK Web Server** + Open your terminal, navigate to the root directory that contains the + `live_bidi_streaming_agent` folder, and execute the following command: + ```bash + adk web + ``` + +2. **Access the ADK Web UI** + Once the server is running, open your web browser and navigate to the URL + provided in the terminal (it will typically be `http://localhost:8000`). + +3. **Select the Agent** + In the top-left corner of the ADK Web UI, use the dropdown menu to select + this agent. + +4. **Start Streaming** + Click on either the **Audio** or **Video** icon located near the chat input + box to begin the streaming session. + +5. **Interact with the Agent** + You can now begin talking to the agent, and it will respond in real-time. + +## Usage Notes + +* You only need to click the **Audio** or **Video** button once to initiate the + stream. The current version does not support stopping and restarting the stream + by clicking the button again during a session. + +## Sample Queries + +- Hello, what's the weather in Seattle and New York? +- Could you roll a 6-sided dice for me? +- Could you check if the number you rolled is a prime number or not? diff --git a/contributing/samples/live_bidi_streaming_single_agent/__init__.py b/contributing/samples/live_bidi_streaming_single_agent/__init__.py new file mode 100755 index 00000000..c48963cd --- /dev/null +++ b/contributing/samples/live_bidi_streaming_single_agent/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2025 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 . import agent diff --git a/contributing/samples/live_bidi_streaming_agent/agent.py b/contributing/samples/live_bidi_streaming_single_agent/agent.py similarity index 100% rename from contributing/samples/live_bidi_streaming_agent/agent.py rename to contributing/samples/live_bidi_streaming_single_agent/agent.py diff --git a/contributing/samples/live_bidi_streaming_agent/readme.md b/contributing/samples/live_bidi_streaming_single_agent/readme.md similarity index 100% rename from contributing/samples/live_bidi_streaming_agent/readme.md rename to contributing/samples/live_bidi_streaming_single_agent/readme.md