### Install Dependencies and Run App Source: https://adk.dev/integrations/ag-ui/index Install project dependencies and start the development servers for the web UI and ADK agent. ```bash npm install && npm run dev ``` -------------------------------- ### Sequential Agent Example Setup (Java) Source: https://adk.dev/agents/workflow-agents/sequential-agents Sets up the main class and method for running a sequential agent example in Java. This includes defining constants for agent names, user IDs, and model names. ```java import com.google.adk.agents.LlmAgent; import com.google.adk.agents.SequentialAgent; import com.google.adk.events.Event; import com.google.adk.runner.InMemoryRunner; import com.google.adk.sessions.Session; import com.google.genai.types.Content; import com.google.genai.types.Part; import io.reactivex.rxjava3.core.Flowable; public class SequentialAgentExample { private static final String APP_NAME = "CodePipelineAgent"; private static final String USER_ID = "test_user_456"; private static final String MODEL_NAME = "gemini-2.0-flash"; public static void main(String[] args) { SequentialAgentExample sequentialAgentExample = new SequentialAgentExample(); sequentialAgentExample.runAgent( "Write a Java function to calculate the factorial of a number."); } public void runAgent(String prompt) { ``` -------------------------------- ### Java Sequential Agent Example Setup Source: https://adk.dev/agents/workflow-agents/sequential-agents/index Initializes a Java Sequential Agent example for running prompts. This sets up the necessary imports and class structure for agent execution. ```java import com.google.adk.agents.LlmAgent; import com.google.adk.agents.SequentialAgent; import com.google.adk.events.Event; import com.google.adk.runner.InMemoryRunner; import com.google.adk.sessions.Session; import com.google.genai.types.Content; import com.google.genai.types.Part; import io.reactivex.rxjava3.core.Flowable; public class SequentialAgentExample { private static final String APP_NAME = "CodePipelineAgent"; private static final String USER_ID = "test_user_456"; private static final String MODEL_NAME = "gemini-2.0-flash"; public static void main(String[] args) { SequentialAgentExample sequentialAgentExample = new SequentialAgentExample(); sequentialAgentExample.runAgent( "Write a Java function to calculate the factorial of a number."); } public void runAgent(String prompt) { ``` -------------------------------- ### Start ADK Web Interface with Custom Options Source: https://adk.dev/runtime/web-interface/index Example of starting the ADK web interface with custom port and session service URI. ```shell adk web --port 3000 --session_service_uri "sqlite:///sessions.db" ``` -------------------------------- ### Start Google ADK Web Server (Maven) Source: https://adk.dev/integrations/application-integration/index Use Maven commands to install and run the ADK Web Server. ```bash mvn install mvn exec:java \ -Dexec.mainClass="com.google.adk.web.AdkWebServer" \ -Dexec.args="--adk.agents.source-dir=src/main/java" \ -Dexec.classpathScope="compile" ``` -------------------------------- ### Go Agent with Instructions Source: https://adk.dev/agents/llm-agents/index Example of creating a Go LlmAgent, defining its purpose, and providing instructions that guide its interaction flow and tool usage, including example queries and responses. ```go // Example: Adding instructions agent, err := llmagent.New(llmagent.Config{ Name: "capital_agent", Model: model, Description: "Answers user questions about the capital city of a given country.", Instruction: `You are an agent that provides the capital city of a country. When a user asks for the capital of a country: 1. Identify the country name from the user's query. 2. Use the 'get_capital_city' tool to find the capital. 3. Respond clearly to the user, stating the capital city. Example Query: "What's the capital of {country}?" Example Response: "The capital of France is Paris."`, // tools will be added next }) ``` -------------------------------- ### Example Agent Setup with AfterTool Callback Source: https://adk.dev/callbacks/types-of-callbacks This function demonstrates how to set up an agent with a specific tool ('getCapitalCity') and an 'AfterTool' callback. It initializes the model, creates the tool, and configures the agent with the callback. ```go func runAfterToolExample() { ctx := context.Background() geminiModel, err := gemini.NewModel(ctx, modelName, &genai.ClientConfig{}) if err != nil { log.Fatalf("FATAL: Failed to create model: %v", err) } capitalTool, err := functiontool.New(functiontool.Config{ Name: "getCapitalCity", Description: "Retrieves the capital city of a given country.", }, getCapitalCity) if err != nil { log.Fatalf("FATAL: Failed to create function tool: %v", err) } llmCfg := llmagent.Config{ Name: "AgentWithAfterToolCallback", Model: geminiModel, Tools: []tool.Tool{capitalTool}, AfterToolCallbacks: []llmagent.AfterToolCallback{onAfterTool}, Instruction: "You are an agent that finds capital cities. " } } ``` -------------------------------- ### LLM Agent Example Setup (Java) Source: https://adk.dev/agents/llm-agents/index Provides the necessary imports and constant definitions for setting up an LLM Agent example in Java. This includes model names, agent names, user IDs, and session IDs. ```java import com.google.adk.agents.LlmAgent; import com.google.adk.events.Event; import com.google.adk.runner.Runner; import com.google.adk.sessions.InMemorySessionService; import com.google.adk.sessions.Session; import com.google.adk.tools.Annotations; import com.google.adk.tools.FunctionTool; import com.google.genai.types.Content; import com.google.genai.types.Part; import com.google.genai.types.Schema; import io.reactivex.rxjava3.core.Flowable; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; public class LlmAgentExample { // --- 1. Define Constants --- private static final String MODEL_NAME = "gemini-2.0-flash"; private static final String APP_NAME = "capital_agent_tool"; private static final String USER_ID = "test_user_456"; private static final String SESSION_ID_TOOL_AGENT = "session_tool_agent_xyz"; private static final String SESSION_ID_SCHEMA_AGENT = "session_schema_agent_xyz"; // --- 2. Define Schemas --- ``` -------------------------------- ### Full Example: Parallel Web Research Setup Source: https://adk.dev/agents/workflow-agents/parallel-agents This Python code sets up multiple LlmAgents, each configured to research a specific topic using Google Search. These agents are intended to be run in parallel. ```python from google.adk.agents.parallel_agent import ParallelAgent from google.adk.agents.llm_agent import LlmAgent from google.adk.agents.sequential_agent import SequentialAgent from google.adk.tools import google_search # --- Constants --- GEMINI_MODEL = "gemini-2.5-flash" # --- 1. Define Researcher Sub-Agents (to run in parallel) --- # Researcher 1: Renewable Energy researcher_agent_1 = LlmAgent( name="RenewableEnergyResearcher", model=GEMINI_MODEL, instruction=""" You are an AI Research Assistant specializing in energy. Research the latest advancements in 'renewable energy sources'. Use the Google Search tool provided. ``` -------------------------------- ### Basic RoutedAgent Example Source: https://adk.dev/agents/routing/index Demonstrates creating two LlmAgents and routing between them using a configuration value. This setup allows dynamic agent selection at runtime. ```typescript import { LlmAgent, RoutedAgent, InMemoryRunner } from '@google/adk'; const agentA = new LlmAgent({ name: 'agent_a', model: 'gemini-flash-latest', instruction: 'You are Agent A. Always identify yourself as Agent A.', }); const agentB = new LlmAgent({ name: 'agent_b', model: 'gemini-flash-latest', instruction: 'You are Agent B. Always identify yourself as Agent B.', }); // External configuration that can change at runtime const config = { selectedAgent: 'agent_a' }; const routedAgent = new RoutedAgent({ name: 'my_routed_agent', agents: { agent_a: agentA, agent_b: agentB }, router: () => config.selectedAgent, }); const runner = new InMemoryRunner({ agent: routedAgent, appName: 'my_app', }); const session = await runner.sessionService.createSession({ appName: 'my_app', userId: 'user_1', }); const run = runner.runAsync({ userId: 'user_1', sessionId: session.id, newMessage: { role: 'user', parts: [{ text: 'Who are you?' }] }, }); for await (const event of run) { if (event.content?.parts?.[0]?.text) { console.log(event.content.parts[0].text); } } ``` -------------------------------- ### Conceptual Setup: LLM Transfer in Java Source: https://adk.dev/agents/custom-agents/index Provides an example of setting up LLM agents for delegation and transfer in Java. Uses the ADK agents library. ```java // Conceptual Setup: LLM Transfer import com.google.adk.agents.LlmAgent; LlmAgent bookingAgent = LlmAgent.builder() .name("Booker") .description("Handles flight and hotel bookings.") .build(); LlmAgent infoAgent = LlmAgent.builder() .name("Info") .description("Provides general information and answers questions.") .build(); // Define the coordinator agent LlmAgent coordinator = LlmAgent.builder() .name("Coordinator") .model("gemini-flash-latest") // Or your desired model .instruction("You are an assistant. Delegate booking tasks to Booker and info requests to Info.") .description("Main coordinator.") // AutoFlow will be used by default (implicitly) because subAgents are present // and transfer is not disallowed. .subAgents(bookingAgent, infoAgent) .build(); // If coordinator receives "Book a flight", its LLM should generate: // FunctionCall.builder.name("transferToAgent").args(ImmutableMap.of("agent_name", "Booker")).build() // ADK framework then routes execution to bookingAgent. ``` -------------------------------- ### Java: Setup for AfterModel Callback Example Source: https://adk.dev/callbacks/types-of-callbacks/index This Java code sets up constants and the main method for an `AfterModelCallbackExample`. It defines agent and model names, instructions, and parameters for session management and text replacement within a callback context. ```java import com.google.adk.agents.LlmAgent; import com.google.adk.agents.CallbackContext; import com.google.adk.events.Event; import com.google.adk.models.LlmResponse; import com.google.adk.runner.InMemoryRunner; import com.google.adk.sessions.Session; import com.google.common.collect.ImmutableList; import com.google.genai.types.Content; import com.google.genai.types.Part; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; public class AfterModelCallbackExample { // --- Define Constants --- private static final String AGENT_NAME = "AfterModelCallbackAgent"; private static final String MODEL_NAME = "gemini-2.0-flash"; private static final String AGENT_INSTRUCTION = "You are a helpful assistant."; private static final String AGENT_DESCRIPTION = "An LLM agent demonstrating after_model_callback"; // For session and runner private static final String APP_NAME = "AfterModelCallbackAgentApp"; private static final String USER_ID = "user_1"; // For text replacement private static final String SEARCH_TERM = "joke"; private static final String REPLACE_TERM = "funny story"; private static final Pattern SEARCH_PATTERN = Pattern.compile("\\b" + Pattern.quote(SEARCH_TERM) + "\\b", Pattern.CASE_INSENSITIVE); public static void main(String[] args) { AfterModelCallbackExample example = new AfterModelCallbackExample(); example.defineAgentAndRun(); } ``` -------------------------------- ### LLM Agent Setup with BuiltInPlanner and Tool Source: https://adk.dev/agents/llm-agents Example of setting up an LLM Agent with BuiltInPlanner, including necessary imports for agent, runner, session, artifact services, and planner configurations. Also shows a sample tool function. ```python from dotenv import load_dotenv import asyncio import os from google.genai import types from google.adk.agents.llm_agent import LlmAgent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService # Optional from google.adk.planners import BasePlanner, BuiltInPlanner, PlanReActPlanner from google.adk.models import LlmRequest from google.genai.types import ThinkingConfig from google.genai.types import GenerateContentConfig import datetime from zoneinfo import ZoneInfo APP_NAME = "weather_app" USER_ID = "1234" SESSION_ID = "session1234" def get_weather(city: str) -> dict: """Retrieves the current weather report for a specified city. Args: city (str): The name of the city for which to retrieve the weather report. Returns: dict: status and result or error msg. ``` -------------------------------- ### Long-Running Function Tool Setup (Java) Source: https://adk.dev/tools-custom/function-tools/index Initializes a LongRunningFunctionTool and sets up the necessary components for an example. This code snippet is a starting point for implementing long-running functions in Java using the ADK. ```java import com.google.adk.agents.LlmAgent; import com.google.adk.events.Event; import com.google.adk.runner.InMemoryRunner; import com.google.adk.runner.Runner; import com.google.adk.sessions.Session; import com.google.adk.tools.Annotations.Schema; import com.google.adk.tools.LongRunningFunctionTool; import com.google.adk.tools.ToolContext; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.genai.types.Content; import com.google.genai.types.FunctionCall; import com.google.genai.types.FunctionResponse; import com.google.genai.types.Part; import java.util.Optional; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; public class LongRunningFunctionExample { private static String USER_ID = "user123"; ``` -------------------------------- ### TypeScript Runner Start Callback Source: https://adk.dev/plugins Example of a `beforeRunCallback` in TypeScript. This function is called after `runner.run()` and before agent execution, providing an opportunity for global setup. It can return a `Content` object to modify the input. ```typescript async beforeRunCallback(invocationContext: InvocationContext): Promise { // Your implementation here } ``` -------------------------------- ### Java Runner Start Callback Source: https://adk.dev/plugins Example of a `beforeRunCallback` in Java. This method is executed after `runner.run()` is called, allowing for initial setup before agent processing. It returns a `Maybe` which can be used to replace the input. ```java @Override public Maybe beforeRunCallback(InvocationContext invocationContext) { // Your implementation here return Maybe.empty(); } ``` -------------------------------- ### Main Method for Tool and Agent Setup Source: https://adk.dev/tools-custom This main method demonstrates the setup of a FunctionTool for customer support and an LLM agent. It defines the tool's method and configures the agent with a model, name, description, and instructions. ```java public static void main(String[] args) throws NoSuchMethodException { FunctionTool escalationTool = FunctionTool.create( CustomerSupportAgentApp.class.getMethod( "checkAndTransfer", String.class, ToolContext.class)); LlmAgent supportAgent = LlmAgent.builder() .model(MODEL_ID) .name("support_agent") .description(""" The dedicated support agent. Mentions it is a support handler and helps the user with their urgent issue. """) .instruction(""" You are the dedicated support agent. Mentioned you are a support handler and please help the user with their urgent issue. """) ``` -------------------------------- ### Create Main Entry Point Source: https://adk.dev/get-started/kotlin/index Create a Main.kt file to run and interact with your agent from the command line using ReplRunner. ```kotlin package com.example.agent import com.google.adk.kt.runners.ReplRunner fun main() { ReplRunner(HelloTimeAgent.rootAgent).start() } ``` -------------------------------- ### File System MCP Server Example Source: https://adk.dev/tools-custom/mcp-tools An example demonstrating the setup and usage of a File System MCP Server with ADK agents. ```python # Assume McpToolset is imported and initialized as self.mcp_toolset # Example: Accessing a file system MCP server # Define agent with McpToolset class FileSystemAgent: def __init__(self): self.mcp_toolset = McpToolset() def read_file(self, file_path): # Use McpToolset to read a file via the MCP server content = self.mcp_toolset.read_file(file_path) return content def write_file(self, file_path, data): # Use McpToolset to write to a file via the MCP server self.mcp_toolset.write_file(file_path, data) # Example usage: agent = FileSystemAgent() file_content = agent.read_file("/path/to/your/file.txt") print(file_content) agent.write_file("/path/to/output.txt", "New content") ``` -------------------------------- ### Load Skills from File System (Go) Source: https://adk.dev/skills/index Initializes a `SkillToolset` using a `FileSystemSource` in Go. This example shows how to set up the source and create the toolset, with comments indicating optional wrappers for preloading. ```go import ( "os" "google.golang.org/adk/tool/skilltoolset/skill" "google.golang.org/adk/tool/skilltoolset" ) // ... source := skill.NewFileSystemSource(os.DirFS("./skills")) // This example doesn't use any optional wrappers, but you can use them if // needed, e.g.: // source, _, err = skill.WithFrontmatterPreloadSource(ctx, source) // source, _, err = skill.WithCompletePreloadSource(ctx, source) // For more information about these and other wrappers, see // https://pkg.go.dev/google.golang.org/adk/tool/skilltoolset/skill#Source. skillToolset, err := skilltoolset.New(ctx, skilltoolset.Config{ Source: source, }) if err != nil { // handle error } ``` -------------------------------- ### Running an Example with BeforeTool Callback Source: https://adk.dev/callbacks/types-of-callbacks Sets up an LLM agent with a 'getCapitalCity' tool and registers the 'onBeforeTool' callback. This demonstrates how to integrate custom callbacks into agent behavior. ```go func runBeforeToolExample() { ctx := context.Background() geminiModel, err := gemini.NewModel(ctx, modelName, &genai.ClientConfig{}) if err != nil { log.Fatalf("FATAL: Failed to create model: %v", err) } capitalTool, err := functiontool.New(functiontool.Config{ Name: "getCapitalCity", Description: "Retrieves the capital city of a given country." }, getCapitalCity) if err != nil { log.Fatalf("FATAL: Failed to create function tool: %v", err) } llmCfg := llmagent.Config{ Name: "AgentWithBeforeToolCallback", Model: geminiModel, Tools: []tool.Tool{capitalTool}, BeforeToolCallbacks: []llmagent.BeforeToolCallback{onBeforeTool}, Instruction: "You are an agent that can find capital cities." } } ``` -------------------------------- ### Create Web Main Entry Point Source: https://adk.dev/get-started/kotlin/index Create a WebMain.kt file to start the ADK web server for interacting with your agent. ```kotlin package com.example.agent import com.google.adk.kt.artifacts.InMemoryArtifactService import com.google.adk.kt.sessions.InMemorySessionService import com.google.adk.kt.webserver.AdkWebServer import com.google.adk.kt.webserver.loaders.SingleAgentLoader import com.google.adk.kt.webserver.telemetry.ApiServerSpanExporter fun main() { val agent = HelloTimeAgent.rootAgent val sessionService = InMemorySessionService() val artifactService = InMemoryArtifactService() val server = AdkWebServer( port = 8080, sessionService = sessionService, artifactService = artifactService, agentLoader = SingleAgentLoader(agent), apiServerSpanExporter = ApiServerSpanExporter(), ) println("Starting ADK web server on http://localhost:8080...") server.start(wait = true) } ``` -------------------------------- ### Go Runner Start Callback Source: https://adk.dev/plugins Example of a `BeforeRunCallback` in Go. This method is invoked after `runner.run()` and before the agent starts its work. It can return a `genai.Content` object to alter the initial user message. ```go func (p *MyPlugin) BeforeRunCallback(ctx agent.InvocationContext) (*genai.Content, error) { // Your implementation here return nil, nil } ``` -------------------------------- ### Specify Example Dataset for Optimization Source: https://adk.dev/optimize/index Define the evaluation dataset in JSON format to guide the agent optimization process. This file includes conversation examples and expected final responses. ```json { "eval_set_id": "train_eval_set", "name": "train_eval_set", "eval_cases": [ { "eval_id": "simple", "conversation": [ { "invocation_id": "inv1", "user_content": { "parts": [ {"text": "Is 7 prime?"} ], "role": "user" }, "final_response": { "parts": [ {"text": "7 is a prime number."} ], "role": "model" } } ], "session_input": { "app_name": "hello_world", "user_id": "user" } }, { "eval_id": "is_good", "conversation": [ { "invocation_id": "inv1", "user_content": { "parts": [ {"text": "Is 4 a bad number?"} ], "role": "user" }, "final_response": { "parts": [ {"text": "4 is not prime so it is a good number."} ], "role": "model" } } ], "session_input": { "app_name": "hello_world", "user_id": "user" } }, { "eval_id": "is_bad", "conversation": [ { "invocation_id": "inv1", "user_content": { "parts": [ {"text": "Is 5 a bad number?"} ], "role": "user" }, "final_response": { "parts": [ {"text": "5 is prime so it is a bad number."} ], "role": "model" } } ], "session_input": { "app_name": "hello_world", "user_id": "user" } } ] } ``` -------------------------------- ### Go: Initialize LlmAgent with Instructions Source: https://adk.dev/agents/llm-agents Example of creating a new LlmAgent in Go using a configuration struct. It includes setting the agent's name, model, description, and a detailed instruction string for finding capital cities. ```go // Example: Adding instructions agent, err := llmagent.New(llmagent.Config{ Name: "capital_agent", Model: model, Description: "Answers user questions about the capital city of a given country.", Instruction: `You are an agent that provides the capital city of a country. When a user asks for the capital of a country: 1. Identify the country name from the user's query. 2. Use the 'get_capital_city' tool to find the capital. 3. Respond clearly to the user, stating the capital city. Example Query: "What's the capital of {country}?" Example Response: "The capital of France is Paris."`, // tools will be added next }) ``` -------------------------------- ### Local Server Output (TypeScript) Source: https://adk.dev/runtime/api-server Example output when the API server starts successfully for a TypeScript agent. ```text +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://localhost:8000. | +-----------------------------------------------------------------------------+ ``` -------------------------------- ### Local Server Output (Python) Source: https://adk.dev/runtime/api-server Example output when the API server starts successfully for a Python agent. ```text INFO: Started server process [12345] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://localhost:8000 (Press CTRL+C to quit) ``` -------------------------------- ### Run Agent Examples (Python) Source: https://adk.dev/integrations/code-execution Sets up and runs asynchronous agent calls for predefined queries. Includes error handling for environments where asyncio might already be running. ```python # Main async function to run the examples async def main(): await call_agent_async("Calculate the value of (5 + 7) * 3") await call_agent_async("What is 10 factorial?") # Execute the main async function try: asyncio.run(main()) except RuntimeError as e: # Handle specific error when running asyncio.run in an already running loop (like Jupyter/Colab) if "cannot be called from a running event loop" in str(e): print("\nRunning in an existing event loop (like Colab/Jupyter).") print("Please run `await main()` in a notebook cell instead.") # If in an interactive environment like a notebook, you might need to run: # await main() else: raise e # Re-raise other runtime errors ``` -------------------------------- ### Run Agent with Tools (Python) Source: https://adk.dev/tools-custom Demonstrates how to set up and run an agent with multiple tools sequentially. Ensure session and runner are correctly initialized before calling the agent. ```python import asyncio from adk.agent import Agent from adk.runner import Runner from adk.session import InMemorySessionService from adk.types import Content, Part APP_NAME = "my-app" USER_ID = "user-123" SESSION_ID = "session-abc" # Assume weather_tool and sentiment_tool are defined elsewhere # For demonstration purposes, let's define dummy tools: class DummyTool: def __init__(self, name): self.name = name def __call__(self, *args, **kwargs): print(f"Executing tool: {self.name}") return {"result": f"Output from {self.name}"} weather_tool = DummyTool("weather_tool") sentiment_tool = DummyTool("sentiment_tool") # Assume weather_sentiment_agent is a pre-configured Agent instance # For demonstration purposes, let's define a dummy agent: class DummyAgent: def __init__(self, tools): self.tools = tools async def __call__(self, user_id, session_id, new_message): print(f"Agent received query: {new_message.parts[0].text}") # Simulate tool execution based on query if "weather" in new_message.parts[0].text.lower(): tool_result = weather_tool() elif "sentiment" in new_message.parts[0].text.lower(): tool_result = sentiment_tool() else: tool_result = "Default agent response." # Simulate returning a final response event return [Runner.Event(content=Content(role='model', parts=[Part(text=str(tool_result))]), is_final=True)] weather_sentiment_agent = DummyAgent(tools=[weather_tool, sentiment_tool]) async def main(): """Main function to run the agent asynchronously.""" # Session and Runner Setup session_service = InMemorySessionService() # Use 'await' to correctly create the session await session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID) runner = Runner(agent=weather_sentiment_agent, app_name=APP_NAME, session_service=session_service) # Agent Interaction query = "weather in london?" print(f"User Query: {query}") content = Content(role='user', parts=[Part(text=query)]) # The runner's run method handles the async loop internally events = runner.run(user_id=USER_ID, session_id=SESSION_ID, new_message=content) for event in events: if event.is_final_response(): final_response = event.content.parts[0].text print("Agent Response:", final_response) # Standard way to run the main async function if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Maven Compile Command Output Source: https://adk.dev/get-started/streaming/quickstart-streaming-java/index Example output of the 'mvn compile' command, indicating a successful project setup. ```shell $ mvn compile [INFO] Scanning for projects... [INFO] [INFO] --------------------< adk-agents:adk-agents >-------------------- [INFO] Building adk-agents 1.0-SNAPSHOT [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- resources:3.3.1:resources (default-resources) @ adk-demo --- [INFO] skip non existing resourceDirectory /home/user/adk-demo/src/main/resources [INFO] [INFO] --- compiler:3.13.0:compile (default-compile) @ adk-demo --- [INFO] Nothing to compile - all classes are up to date. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.347 s [INFO] Finished at: 2025-05-06T15:38:08Z [INFO] ------------------------------------------------------------------------ ``` -------------------------------- ### Main Method for Calculator Agent Setup Source: https://adk.dev/agents/llm-agents Sets up and runs a calculator agent. This demonstrates how to build an agent with a specific name, model, tools (like code execution), and instructions for mathematical calculations. ```Java public static void main(String[] args) { BuiltInCodeExecutionTool codeExecutionTool = new BuiltInCodeExecutionTool(); BaseAgent codeAgent = LlmAgent.builder() .name(AGENT_NAME) .model(GEMINI_MODEL) .tools(ImmutableList.of(codeExecutionTool)) .instruction( """ You are a calculator agent. When given a mathematical expression, write and execute Python code to calculate the result. Return only the final numerical result as plain text, without markdown or code blocks. """") .description("Executes Python code to perform calculations.") .build(); InMemorySessionService sessionService = new InMemorySessionService(); Runner runner = new Runner(codeAgent, APP_NAME, null, sessionService); callAgent(runner, "Calculate the value of (5 + 7) * 3"); callAgent(runner, "What is 10 factorial?"); } ``` -------------------------------- ### Python Tool for Getting Stock Price Source: https://adk.dev/tools-custom/function-tools This Python function retrieves the current stock price for a given symbol using the yfinance library. Ensure you have `pip install yfinance` installed before use. It returns the closing price or None if an error occurs. ```python # 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 google.adk.agents import Agent from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.genai import types import yfinance as yf APP_NAME = "stock_app" USER_ID = "1234" SESSION_ID = "session1234" def get_stock_price(symbol: str): """ Retrieves the current stock price for a given symbol. Args: symbol (str): The stock symbol (e.g., "AAPL", "GOOG"). Returns: float: The current stock price, or None if an error occurs. """ try: stock = yf.Ticker(symbol) historical_data = stock.history(period="1d") if not historical_data.empty: current_price = historical_data['Close'].iloc[-1] return current_price else: return None except Exception as e: print(f"Error retrieving stock price for {symbol}: {e}") return None stock_price_agent = Agent( model='gemini-2.0-flash', name='stock_agent', instruction= 'You are an agent who retrieves stock prices. If a ticker symbol is provided, fetch the current price. If only a company name is given, first perform a Google search to find the correct ticker symbol before retrieving the stock price. If the provided ticker symbol is invalid or data cannot be retrieved, inform the user that the stock price could not be found.', description='This agent specializes in retrieving real-time stock prices. Given a stock ticker symbol (e.g. AAPL, GOOG, MSFT) or the stock name, use the tools and reliable data sources to provide the most up-to-date price.', tools=[get_stock_price], # You can add Python functions directly to the tools list; they will be automatically wrapped as FunctionTools. ) ``` -------------------------------- ### Unsupported Sub-agent with Built-in Tools (Kotlin) Source: https://adk.dev/tools/limitations/index This Kotlin example illustrates an unsupported configuration where sub-agents are set up with built-in tools. This is not a valid setup. ```kotlin val searchAgent = LlmAgent( model = Gemini(name = "gemini-flash-latest"), name = "SearchAgent", instruction = Instruction("You're a specialist in Google Search"), tools = listOf(GoogleSearchTool()) ) val codingAgent = LlmAgent( model = Gemini(name = "gemini-flash-latest"), name = "CodeAgent", instruction = Instruction("You're a specialist in Code Execution") // Kotlin currently doesn't have a BuiltInCodeExecutionTool in core ) val rootAgent = LlmAgent( name = "RootAgent", model = Gemini(name = "gemini-flash-latest"), description = "Root Agent", subAgents = listOf(searchAgent, codingAgent) // Not supported when sub-agents use built-in tools ) ``` -------------------------------- ### Python: Initialize LlmAgent with Instructions Source: https://adk.dev/agents/llm-agents Example of initializing an LlmAgent in Python, defining its model, name, description, and a detailed instruction string that includes tool usage guidance and few-shot examples. ```python capital_agent = LlmAgent( model="gemini-flash-latest", name="capital_agent", description="Answers user questions about the capital city of a given country.", instruction="""You are an agent that provides the capital city of a country. When a user asks for the capital of a country: 1. Identify the country name from the user's query. 2. Use the `get_capital_city` tool to find the capital. 3. Respond clearly to the user, stating the capital city. Example Query: "What's the capital of {country}?" Example Response: "The capital of France is Paris." """, # tools will be added next ) ``` -------------------------------- ### Unsupported Sub-agent with Built-in Tools (TypeScript) Source: https://adk.dev/tools/limitations/index This TypeScript example illustrates an unsupported configuration where sub-agents utilize built-in tools. This setup is not functional. ```typescript import {Agent, BuiltInCodeExecutor} from '@google/adk'; const urlContextAgent = new Agent({ model: 'gemini-flash-latest', name: 'UrlContextAgent', instruction: "You're a specialist in URL Context", tools: [myCustomTool], // Assume myCustomTool is defined }); const codingAgent = new Agent({ model: 'gemini-flash-latest', name: 'CodeAgent', instruction: "You're a specialist in Code Execution", codeExecutor: new BuiltInCodeExecutor(), }); const rootAgent = new Agent({ name: 'RootAgent', model: 'gemini-flash-latest', description: 'Root Agent', subAgents: [urlContextAgent, codingAgent], // NOT supported when sub-agents use built-in tools }); ``` -------------------------------- ### Go: Customer Support Agent with Tool Escalation Source: https://adk.dev/tools-custom/index This Go example sets up a customer support agent that uses a tool to check for query urgency and transfer to a specialized support agent if needed. It demonstrates agent and tool configuration, session management, and running agent interactions. ```go // 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. package main import ( "context" "fmt" "log" "strings" "google.golang.org/adk/agent" "google.golang.org/adk/agent/llmagent" "google.golang.org/adk/model/gemini" "google.golang.org/adk/runner" "google.golang.org/adk/session" "google.golang.org/adk/tool" "google.golang.org/adk/tool/functiontool" "google.golang.org/genai" ) type checkAndTransferArgs struct { Query string `json:"query" jsonschema:"The user's query to check for urgency." } type checkAndTransferResult struct { Status string `json:"status"` } func checkAndTransfer(ctx tool.Context, args checkAndTransferArgs) (checkAndTransferResult, error) { if strings.Contains(strings.ToLower(args.Query), "urgent") { fmt.Println("Tool: Detected urgency, transferring to the support agent.") ctx.Actions().TransferToAgent = "support_agent" return checkAndTransferResult{Status: "Transferring to the support agent..."}, nil } return checkAndTransferResult{Status: fmt.Sprintf("Processed query: '%s'. No further action needed.", args.Query)}, nil } func main() { ctx := context.Background() model, err := gemini.NewModel(ctx, "gemini-2.0-flash", &genai.ClientConfig{}) if err != nil { log.Fatal(err) } supportAgent, err := llmagent.New(llmagent.Config{ Name: "support_agent", Model: model, Instruction: "You are the dedicated support agent. Mentioned you are a support handler and please help the user with their urgent issue.", }) if err != nil { log.Fatal(err) } checkAndTransferTool, err := functiontool.New( functiontool.Config{ Name: "check_and_transfer", Description: "Checks if the query requires escalation and transfers to another agent if needed.", }, checkAndTransfer, ) if err != nil { log.Fatal(err) } mainAgent, err := llmagent.New(llmagent.Config{ Name: "main_agent", Model: model, Instruction: "You are the first point of contact for customer support of an analytics tool. Answer general queries. If the user indicates urgency, use the 'check_and_transfer' tool.", Tools: []tool.Tool{checkAndTransferTool}, SubAgents: []agent.Agent{supportAgent}, }) if err != nil { log.Fatal(err) } sessionService := session.InMemoryService() runner, err := runner.New(runner.Config{ AppName: "customer_support_agent", Agent: mainAgent, SessionService: sessionService, }) if err != nil { log.Fatal(err) } session, err := sessionService.Create(ctx, &session.CreateRequest{ AppName: "customer_support_agent", UserID: "user1234", }) if err != nil { log.Fatal(err) } run(ctx, runner, session.Session.ID(), "this is urgent, i cant login") } func run(ctx context.Context, r *runner.Runner, sessionID string, prompt string) { fmt.Printf("\n> %s\n", prompt) events := r.Run( ctx, "user1234", sessionID, genai.NewContentFromText(prompt, genai.RoleUser), agent.RunConfig{ StreamingMode: agent.StreamingModeNone, }, ) for event, err := range events { if err != nil { log.Fatalf("ERROR during agent execution: %v", err) } if event.Content.Parts[0].Text != "" { fmt.Printf("Agent Response: %s\n", event.Content.Parts[0].Text) } } } ``` -------------------------------- ### Define Agent with Before Model Callback Source: https://adk.dev/callbacks/types-of-callbacks Set up an LlmAgent and configure it to use a before_model_callback. This example demonstrates how to integrate a custom callback function during agent setup. ```Java LlmAgent myLlmAgent = LlmAgent.builder() .name(AGENT_NAME) .model(MODEL_NAME) .instruction(AGENT_INSTRUCTION) .description(AGENT_DESCRIPTION) .beforeModelCallback(this::simpleBeforeModelModifier) .build(); ``` -------------------------------- ### Instantiate and Use Tools with Agent Source: https://adk.dev/tools-custom Demonstrates instantiating a custom toolset and an individual tool, then configuring an LlmAgent to use both. ```python # Instantiate the toolset math_toolset_instance = SimpleMathToolset(prefix="calculator") # Define an individual tool (not part of the toolset) greet_tool = FunctionTool(func=greet_user) # Define an agent that uses both the individual tool and the toolset calculator_agent = LlmAgent( name="CalculatorAgent", model="gemini-flash-latest", # Replace with your desired model instruction="You are a helpful calculator and greeter. Use 'greet_user' for greetings. " ) ``` -------------------------------- ### Setup and Run Agent with After Agent Callback Source: https://adk.dev/callbacks/types-of-callbacks/index Demonstrates setting up an `LlmAgent` with an `after_agent_callback` and running it through `InMemoryRunner` in two scenarios: one where the callback uses the agent's output, and another where it replaces it based on session state. ```python # --- 2. Setup Agent with Callback --- llm_agent_with_after_cb = LlmAgent( name="MySimpleAgentWithAfter", model=GEMINI_2_FLASH, instruction="You are a simple agent. Just say 'Processing complete!'", description="An LLM agent demonstrating after_agent_callback for output modification", after_agent_callback=modify_output_after_agent, # Assign the callback here ) ``` ```python # --- 3. Setup Runner and Sessions using InMemoryRunner --- async def main(): app_name = "after_agent_demo" user_id = "test_user_after" session_id_normal = "session_run_normally" session_id_modify = "session_modify_output" # Use InMemoryRunner - it includes InMemorySessionService runner = InMemoryRunner(agent=llm_agent_with_after_cb, app_name=app_name) # Get the bundled session service to create sessions session_service = runner.session_service # Create session 1: Agent output will be used as is (default empty state) session_service.create_session( app_name=app_name, user_id=user_id, session_id=session_id_normal, # No initial state means 'add_concluding_note' will be False in the callback check ) # print(f"Session '{session_id_normal}' created with default state.") # Create session 2: Agent output will be replaced by the callback session_service.create_session( app_name=app_name, user_id=user_id, session_id=session_id_modify, state={"add_concluding_note": True}, # Set the state flag here ) # print(f"Session '{session_id_modify}' created with state={{'add_concluding_note': True}}.") # --- Scenario 1: Run where callback allows agent's original output --- print( "\n" + "=" * 20 + f" SCENARIO 1: Running Agent on Session '{session_id_normal}' (Should Use Original Output) " + "=" * 20 ) async for event in runner.run_async( user_id=user_id, session_id=session_id_normal, new_message=types.Content( role="user", parts=[types.Part(text="Process this please.")] ), ): # Print final output (either from LLM or callback override) if event.is_final_response() and event.content: print( f"Final Output: [{event.author}] {event.content.parts[0].text.strip()}" ) elif event.is_error(): print(f"Error Event: {event.error_details}") # --- Scenario 2: Run where callback replaces the agent's output --- print( "\n" + "=" * 20 + f" SCENARIO 2: Running Agent on Session '{session_id_modify}' (Should Replace Output) " + "=" * 20 ) async for event in runner.run_async( user_id=user_id, session_id=session_id_modify, new_message=types.Content( role="user", parts=[types.Part(text="Process this and add note.")] ), ): # Print final output (either from LLM or callback override) if event.is_final_response() and event.content: print( f"Final Output: [{event.author}] {event.content.parts[0].text.strip()}" ) elif event.is_error(): print(f"Error Event: {event.error_details}") # --- 4. Execute --- # In a Python script: # import asyncio # if __name__ == "__main__": # # Make sure GOOGLE_API_KEY environment variable is set if not using Agent Platform auth # # Or ensure Application Default Credentials (ADC) are configured for Agent Platform # asyncio.run(main()) # In a Jupyter Notebook or similar environment: await main() ```