diff --git a/README.md b/README.md index 4632a902f0e..2bc53c45a68 100644 --- a/README.md +++ b/README.md @@ -1,151 +1,46 @@ -# Agent Development Kit (ADK) +# KRNL Key Automation Script -[](LICENSE) -[](https://github.com/google/adk-python/actions/workflows/python-unit-tests.yml) -[](https://www.reddit.com/r/agentdevelopmentkit/) -[](https://deepwiki.com/google/adk-python) +This Python script automates the process of retrieving KRNL keys and injecting them into the KRNL exploit. - -
-
-
-### Evaluate Agents
-
-```bash
-adk eval \
- samples_for_testing/hello_world \
- samples_for_testing/hello_world/hello_world_eval_set_001.evalset.json
-```
-
-## 🤝 Contributing
-
-We welcome contributions from the community! Whether it's bug reports, feature requests, documentation improvements, or code contributions, please see our
-- [General contribution guideline and flow](https://google.github.io/adk-docs/contributing-guide/).
-- Then if you want to contribute code, please read [Code Contributing Guidelines](./CONTRIBUTING.md) to get started.
-
-## Vibe Coding
-
-If you are to develop agent via vibe coding the [llms.txt](./llms.txt) and the [llms-full.txt](./llms-full.txt) can be used as context to LLM. While the former one is a summarized one and the later one has the full information in case your LLM has big enough context window.
-
-## 📄 License
-
-This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.
-
----
-
-*Happy Agent Building!*
+This script is for educational purposes only. Use responsibly and in accordance with applicable terms of service.
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000000..adac1509bc5
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,306 @@
+# Google ADK Documentation
+
+Welcome to the comprehensive documentation for the Google Agent Development Kit (ADK)! This documentation provides detailed information about all public APIs, functions, and components, along with practical examples and usage instructions.
+
+## Documentation Overview
+
+This documentation is organized into several specialized guides to help you understand and use Google ADK effectively:
+
+### 📚 Core Documentation
+
+#### [**User Guide**](user-guide.md)
+**Start here if you're new to Google ADK!**
+
+A comprehensive getting-started guide that covers:
+- Installation and setup instructions
+- Core concepts and terminology
+- Building your first agent step-by-step
+- Working with tools and multi-agent systems
+- Best practices and troubleshooting
+
+Perfect for developers new to agent development or those transitioning from other frameworks.
+
+#### [**API Reference**](api-reference.md)
+**Complete reference for all public APIs**
+
+Detailed documentation for all classes, functions, and interfaces:
+- Core classes (`Agent`, `Runner`)
+- Tools and toolsets (`BaseTool`, built-in tools)
+- Models and LLM integration (`Gemini`, `BaseLlm`)
+- Sessions and state management
+- Type aliases and callback functions
+
+Essential for developers who need detailed API information while building applications.
+
+#### [**Tools Guide**](tools-guide.md)
+**Comprehensive guide to ADK's tool ecosystem**
+
+Everything you need to know about tools:
+- Built-in tools (Google Search, Enterprise Search, etc.)
+- Creating custom tools and toolsets
+- Tool configuration and best practices
+- Integration patterns with APIs and databases
+- Advanced tool development techniques
+
+Perfect for developers building custom tools or integrating external services.
+
+#### [**Examples**](examples.md)
+**Practical examples and usage patterns**
+
+Real-world examples covering:
+- Basic agent examples with progressive complexity
+- Multi-agent systems and coordination patterns
+- Tool integration (REST APIs, databases)
+- Advanced patterns (streaming, state management)
+- Production deployment examples
+- Complete application examples
+
+Ideal for learning through practical examples and understanding implementation patterns.
+
+#### [**Utilities Guide**](utilities-guide.md)
+**Helper functions and utility classes**
+
+Documentation for ADK's utility modules:
+- Model name utilities (parsing, validation)
+- Feature decorators (experimental, WIP features)
+- Instruction utilities (template processing)
+- Variant utilities (Google LLM variants)
+- Usage examples and composition patterns
+
+Useful for advanced developers who want to leverage ADK's utility functions.
+
+---
+
+## Quick Start
+
+### Installation
+
+```bash
+# Install Google ADK
+pip install google-adk
+
+# For development version with latest features
+pip install git+https://github.com/google/adk-python.git@main
+```
+
+### Hello World Example
+
+```python
+from google.adk import Agent, Runner
+from google.adk.sessions import InMemorySessionService
+
+# Create a simple agent
+agent = Agent(
+ name="hello_agent",
+ model="gemini-2.0-flash",
+ instruction="You are a helpful assistant. Be friendly and concise."
+)
+
+# Set up and run
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="hello_world",
+ agent=agent,
+ session_service=session_service
+)
+
+# Interact with the agent
+for event in runner.run(
+ user_id="user123",
+ session_id="session456",
+ new_message="Hello! What can you help me with?"
+):
+ if event.type == "model_response":
+ print(f"Agent: {event.data.get('text', '')}")
+```
+
+For more detailed examples, see the [User Guide](user-guide.md) and [Examples](examples.md).
+
+---
+
+## Architecture Overview
+
+Google ADK is built around four core concepts:
+
+### 🤖 Agents
+The primary building blocks that encapsulate:
+- **Model**: The LLM (e.g., Gemini) that powers the agent
+- **Instructions**: Behavioral guidelines and personality
+- **Tools**: Capabilities and external integrations
+- **Context**: Conversation state and memory
+
+### 🛠️ Tools
+Extensible capabilities that provide:
+- External API access
+- Database operations
+- Custom business logic
+- Inter-agent communication
+
+### 💾 Sessions
+State management for:
+- Conversation history
+- User and session identification
+- Context preservation
+- State persistence
+
+### 🏃 Runners
+Execution orchestration including:
+- Message processing
+- Event generation
+- Service coordination
+- Error handling and recovery
+
+---
+
+## Key Features
+
+### 🔧 **Code-First Development**
+Define agents, tools, and workflows directly in Python with full type safety and IDE support.
+
+```python
+from google.adk import Agent
+from google.adk.tools import google_search, FunctionTool
+
+def calculate_tip(bill: float, percentage: float = 15.0) -> dict:
+ """Calculate tip amount."""
+ tip = bill * (percentage / 100)
+ return {"tip": tip, "total": bill + tip}
+
+agent = Agent(
+ name="helpful_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a helpful assistant with search and calculation capabilities.",
+ tools=[google_search, FunctionTool(func=calculate_tip)]
+)
+```
+
+### 🌐 **Rich Tool Ecosystem**
+Extensive collection of pre-built tools plus easy custom tool creation:
+
+```python
+from google.adk.tools import (
+ google_search, # Web search
+ enterprise_web_search, # Enterprise search
+ url_context, # Web page analysis
+ load_memory, # Memory management
+ AgentTool, # Inter-agent communication
+ VertexAiSearchTool # Custom search
+)
+```
+
+### 🤝 **Multi-Agent Systems**
+Build complex workflows with specialized agents:
+
+```python
+# Specialized agents
+researcher = Agent(name="researcher", tools=[google_search], ...)
+writer = Agent(name="writer", ...)
+editor = Agent(name="editor", ...)
+
+# Coordinator agent
+coordinator = Agent(
+ name="content_team",
+ tools=[AgentTool(agent=researcher), AgentTool(agent=writer), AgentTool(agent=editor)]
+)
+```
+
+### 🚀 **Production Ready**
+Deploy anywhere with built-in support for:
+- FastAPI web services
+- Docker containerization
+- Cloud Run deployment
+- Vertex AI integration
+- Horizontal scaling
+
+### 🔄 **Model Agnostic**
+While optimized for Gemini, ADK supports various LLMs:
+
+```python
+# Gemini models (recommended)
+agent1 = Agent(model="gemini-2.0-flash", ...)
+agent2 = Agent(model="gemini-1.5-pro", ...)
+
+# Custom model integration
+from google.adk.models import BaseLlm
+custom_model = CustomLLM()
+agent3 = Agent(model=custom_model, ...)
+```
+
+---
+
+## Common Use Cases
+
+### 💬 **Conversational AI**
+Build sophisticated chatbots and virtual assistants with memory, tools, and personality.
+
+### 🔍 **Research and Analysis**
+Create agents that can search, analyze, and synthesize information from multiple sources.
+
+### 🏢 **Enterprise Automation**
+Automate business processes with agents that integrate with internal systems and APIs.
+
+### 📝 **Content Creation**
+Build multi-agent workflows for research, writing, editing, and publishing content.
+
+### 🎯 **Specialized Assistants**
+Create domain-specific assistants for coding, data analysis, customer support, etc.
+
+### 🌐 **API Integration**
+Connect AI agents to external services, databases, and enterprise systems.
+
+---
+
+## Getting Help
+
+### 📖 **Documentation Navigation**
+
+1. **New to ADK?** → Start with the [User Guide](user-guide.md)
+2. **Building tools?** → Check the [Tools Guide](tools-guide.md)
+3. **Need API details?** → See the [API Reference](api-reference.md)
+4. **Want examples?** → Browse the [Examples](examples.md)
+5. **Using utilities?** → Read the [Utilities Guide](utilities-guide.md)
+
+### 🔗 **External Resources**
+
+- **[Official Documentation](https://google.github.io/adk-docs)** - Complete documentation website
+- **[Sample Projects](https://github.com/google/adk-samples)** - Example applications and templates
+- **[ADK Web Interface](https://github.com/google/adk-web)** - Browser-based development UI
+- **[Community Forum](https://www.reddit.com/r/agentdevelopmentkit/)** - Community discussions and support
+
+### 🐛 **Troubleshooting**
+
+Common issues and solutions are covered in the [User Guide's Troubleshooting section](user-guide.md#troubleshooting).
+
+For bugs and feature requests:
+- **Python ADK**: [GitHub Issues](https://github.com/google/adk-python/issues)
+- **Documentation**: [Documentation Issues](https://github.com/google/adk-docs/issues)
+
+---
+
+## Version Information
+
+This documentation covers **Google ADK Python** and is compatible with:
+- **Python**: 3.9, 3.10, 3.11, 3.12, 3.13
+- **Google Cloud**: All regions supporting Gemini
+- **Vertex AI**: Agent Engine integration
+- **Deployment**: Cloud Run, containers, local development
+
+---
+
+## Contributing
+
+We welcome contributions to both ADK and its documentation! See:
+- [Contributing Guidelines](https://google.github.io/adk-docs/contributing-guide/)
+- [Code Contributing Guidelines](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md)
+
+---
+
+## License
+
+Google ADK is licensed under the Apache 2.0 License. See the [LICENSE](https://github.com/google/adk-python/blob/main/LICENSE) file for details.
+
+---
+
+**Happy Agent Building!** 🚀
+
+*This documentation was generated to provide comprehensive coverage of Google ADK's public APIs, functions, and components. For the most up-to-date information, visit the [official documentation](https://google.github.io/adk-docs).*
\ No newline at end of file
diff --git a/docs/api-reference.md b/docs/api-reference.md
new file mode 100644
index 00000000000..b0f6f99efc7
--- /dev/null
+++ b/docs/api-reference.md
@@ -0,0 +1,587 @@
+# Google ADK API Reference
+
+This document provides comprehensive API reference documentation for the Google Agent Development Kit (ADK).
+
+## Table of Contents
+
+- [Core Classes](#core-classes)
+ - [Agent](#agent)
+ - [Runner](#runner)
+- [Tools](#tools)
+ - [BaseTool](#basetool)
+ - [Built-in Tools](#built-in-tools)
+- [Models](#models)
+ - [BaseLlm](#basellm)
+ - [Gemini](#gemini)
+- [Sessions](#sessions)
+ - [Session](#session)
+ - [BaseSessionService](#basesessionservice)
+- [Examples](#examples)
+- [Utilities](#utilities)
+
+---
+
+## Core Classes
+
+### Agent
+
+**Class**: `google.adk.agents.LlmAgent`
+
+The main agent class for creating LLM-powered agents.
+
+#### Constructor
+
+```python
+Agent(
+ name: str,
+ model: Union[str, BaseLlm] = '',
+ instruction: Union[str, InstructionProvider] = '',
+ global_instruction: Union[str, InstructionProvider] = '',
+ tools: list[ToolUnion] = [],
+ generate_content_config: Optional[types.GenerateContentConfig] = None,
+ disallow_transfer_to_parent: bool = False,
+ disallow_transfer_to_peers: bool = False,
+ include_contents: Literal['default', 'none'] = 'default',
+ input_schema: Optional[type[BaseModel]] = None,
+ output_schema: Optional[type[BaseModel]] = None,
+ output_key: Optional[str] = None,
+ planner: Optional[BasePlanner] = None,
+ flows: list[BaseLlmFlow] = [],
+ code_executor: Optional[BaseCodeExecutor] = None,
+ before_model_callbacks: Optional[BeforeModelCallback] = None,
+ after_model_callbacks: Optional[AfterModelCallback] = None,
+ before_tool_callbacks: Optional[BeforeToolCallback] = None,
+ after_tool_callbacks: Optional[AfterToolCallback] = None,
+ sub_agents: list[BaseAgent] = [],
+ **kwargs
+)
+```
+
+#### Parameters
+
+- **name** (`str`): A unique identifier for the agent
+- **model** (`Union[str, BaseLlm]`): The LLM model to use (e.g., "gemini-2.0-flash")
+- **instruction** (`Union[str, InstructionProvider]`): Instructions guiding the agent's behavior
+- **global_instruction** (`Union[str, InstructionProvider]`): Instructions for all agents in the agent tree
+- **tools** (`list[ToolUnion]`): List of tools available to the agent
+- **generate_content_config** (`Optional[types.GenerateContentConfig]`): Additional content generation configurations
+- **disallow_transfer_to_parent** (`bool`): Prevents LLM-controlled transfer to parent agent
+- **disallow_transfer_to_peers** (`bool`): Prevents LLM-controlled transfer to peer agents
+- **include_contents** (`Literal['default', 'none']`): Controls content inclusion in model requests
+- **input_schema** (`Optional[type[BaseModel]]`): Schema for input validation when used as a tool
+- **output_schema** (`Optional[type[BaseModel]]`): Schema for output validation
+- **output_key** (`Optional[str]`): Key in session state to store agent output
+- **planner** (`Optional[BasePlanner]`): Planning component for advanced reasoning
+- **flows** (`list[BaseLlmFlow]`): Flow configurations for the agent
+- **code_executor** (`Optional[BaseCodeExecutor]`): Code execution component
+- **before_model_callbacks** (`Optional[BeforeModelCallback]`): Callbacks executed before model invocation
+- **after_model_callbacks** (`Optional[AfterModelCallback]`): Callbacks executed after model invocation
+- **before_tool_callbacks** (`Optional[BeforeToolCallback]`): Callbacks executed before tool invocation
+- **after_tool_callbacks** (`Optional[AfterToolCallback]`): Callbacks executed after tool invocation
+- **sub_agents** (`list[BaseAgent]`): Child agents for multi-agent systems
+
+#### Example Usage
+
+```python
+from google.adk import Agent
+from google.adk.tools import google_search
+
+# Simple agent with Google Search
+search_agent = Agent(
+ name="search_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a helpful assistant that can search the web.",
+ tools=[google_search]
+)
+
+# Multi-agent system
+coordinator = Agent(
+ name="coordinator",
+ model="gemini-2.0-flash",
+ instruction="Coordinate tasks between specialized agents.",
+ sub_agents=[
+ Agent(name="researcher", model="gemini-2.0-flash", tools=[google_search]),
+ Agent(name="writer", model="gemini-2.0-flash", instruction="Write clear summaries")
+ ]
+)
+```
+
+---
+
+### Runner
+
+**Class**: `google.adk.runners.Runner`
+
+The Runner class manages agent execution within sessions, handling message processing, event generation, and service interactions.
+
+#### Constructor
+
+```python
+Runner(
+ *,
+ app_name: str,
+ agent: BaseAgent,
+ plugins: Optional[List[BasePlugin]] = None,
+ artifact_service: Optional[BaseArtifactService] = None,
+ session_service: BaseSessionService,
+ memory_service: Optional[BaseMemoryService] = None,
+ credential_service: Optional[BaseCredentialService] = None,
+)
+```
+
+#### Parameters
+
+- **app_name** (`str`): Application name for the runner
+- **agent** (`BaseAgent`): Root agent to execute
+- **plugins** (`Optional[List[BasePlugin]]`): List of plugins for extended functionality
+- **artifact_service** (`Optional[BaseArtifactService]`): Service for artifact storage and management
+- **session_service** (`BaseSessionService`): Service for session management
+- **memory_service** (`Optional[BaseMemoryService]`): Service for memory management
+- **credential_service** (`Optional[BaseCredentialService]`): Service for credential management
+
+#### Methods
+
+##### `run()`
+
+```python
+def run(
+ self,
+ *,
+ user_id: str,
+ session_id: str,
+ new_message: types.Content,
+ run_config: RunConfig = RunConfig(),
+) -> Generator[Event, None, None]
+```
+
+Synchronous method to run the agent (for local testing).
+
+**Parameters:**
+- **user_id** (`str`): User identifier
+- **session_id** (`str`): Session identifier
+- **new_message** (`types.Content`): New message to process
+- **run_config** (`RunConfig`): Configuration for the run
+
+**Returns:** Generator yielding execution events
+
+##### `run_async()`
+
+```python
+async def run_async(
+ self,
+ *,
+ user_id: str,
+ session_id: str,
+ new_message: types.Content,
+ state_delta: Optional[dict[str, Any]] = None,
+ run_config: RunConfig = RunConfig(),
+) -> AsyncGenerator[Event, None]
+```
+
+Asynchronous method to run the agent (recommended for production).
+
+**Parameters:**
+- **user_id** (`str`): User identifier
+- **session_id** (`str`): Session identifier
+- **new_message** (`types.Content`): New message to process
+- **state_delta** (`Optional[dict[str, Any]]`): State changes to apply
+- **run_config** (`RunConfig`): Configuration for the run
+
+**Returns:** AsyncGenerator yielding execution events
+
+#### Example Usage
+
+```python
+from google.adk import Agent, Runner
+from google.adk.sessions import InMemorySessionService
+
+# Create agent and runner
+agent = Agent(name="assistant", model="gemini-2.0-flash")
+session_service = InMemorySessionService()
+
+runner = Runner(
+ app_name="my_app",
+ agent=agent,
+ session_service=session_service
+)
+
+# Run the agent
+for event in runner.run(
+ user_id="user123",
+ session_id="session456",
+ new_message="Hello, how can you help me?"
+):
+ print(f"Event: {event.type} - {event.data}")
+```
+
+---
+
+## Tools
+
+### BaseTool
+
+**Class**: `google.adk.tools.BaseTool`
+
+Abstract base class for all tools in the ADK framework.
+
+#### Constructor
+
+```python
+BaseTool(
+ *,
+ name: str,
+ description: str,
+ is_long_running: bool = False,
+ custom_metadata: Optional[dict[str, Any]] = None,
+)
+```
+
+#### Parameters
+
+- **name** (`str`): Unique name for the tool
+- **description** (`str`): Description of the tool's functionality
+- **is_long_running** (`bool`): Whether the tool performs long-running operations
+- **custom_metadata** (`Optional[dict[str, Any]]`): Additional tool-specific metadata
+
+#### Abstract Methods
+
+##### `run_async()`
+
+```python
+async def run_async(
+ self, *, args: dict[str, Any], tool_context: ToolContext
+) -> Any
+```
+
+Main execution method for the tool.
+
+**Parameters:**
+- **args** (`dict[str, Any]`): Tool arguments
+- **tool_context** (`ToolContext`): Context containing session information
+
+**Returns:** Tool execution result
+
+#### Example Implementation
+
+```python
+from google.adk.tools import BaseTool
+from google.adk.tools import ToolContext
+
+class CustomCalculatorTool(BaseTool):
+ def __init__(self):
+ super().__init__(
+ name="calculator",
+ description="Performs basic mathematical calculations",
+ )
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ operation = args.get("operation")
+ a = args.get("a")
+ b = args.get("b")
+
+ if operation == "add":
+ return {"result": a + b}
+ elif operation == "multiply":
+ return {"result": a * b}
+ else:
+ return {"error": "Unsupported operation"}
+```
+
+### Built-in Tools
+
+#### Google Search
+
+```python
+from google.adk.tools import google_search
+
+# Use in agent
+agent = Agent(
+ name="search_agent",
+ model="gemini-2.0-flash",
+ tools=[google_search]
+)
+```
+
+Performs web searches using Google Search.
+
+#### Enterprise Search
+
+```python
+from google.adk.tools import enterprise_web_search
+
+# Use in agent
+agent = Agent(
+ name="enterprise_agent",
+ model="gemini-2.0-flash",
+ tools=[enterprise_web_search]
+)
+```
+
+Searches within enterprise content using Google Enterprise Search.
+
+#### URL Context
+
+```python
+from google.adk.tools import url_context
+
+# Use in agent
+agent = Agent(
+ name="web_agent",
+ model="gemini-2.0-flash",
+ tools=[url_context]
+)
+```
+
+Extracts and analyzes content from web URLs.
+
+#### Function Tool
+
+```python
+from google.adk.tools import FunctionTool
+
+def get_weather(location: str) -> str:
+ """Get weather information for a location."""
+ return f"Weather in {location}: Sunny, 75°F"
+
+weather_tool = FunctionTool(func=get_weather)
+
+agent = Agent(
+ name="weather_agent",
+ model="gemini-2.0-flash",
+ tools=[weather_tool]
+)
+```
+
+Wraps Python functions as tools for agent use.
+
+#### Agent Tool
+
+```python
+from google.adk.tools import AgentTool
+
+sub_agent = Agent(name="specialist", model="gemini-2.0-flash")
+agent_tool = AgentTool(agent=sub_agent)
+
+main_agent = Agent(
+ name="main_agent",
+ model="gemini-2.0-flash",
+ tools=[agent_tool]
+)
+```
+
+Allows agents to invoke other agents as tools.
+
+---
+
+## Models
+
+### BaseLlm
+
+**Class**: `google.adk.models.BaseLlm`
+
+Abstract base class for all language models.
+
+### Gemini
+
+**Class**: `google.adk.models.Gemini`
+
+Google's Gemini model implementation.
+
+#### Supported Models
+
+```python
+from google.adk.models import Gemini
+
+# Get list of supported models
+supported_models = Gemini.supported_models()
+print(supported_models)
+```
+
+#### Example Usage
+
+```python
+from google.adk.models import Gemini
+
+# Create Gemini model instance
+gemini = Gemini(model_name="gemini-2.0-flash")
+
+# Use with agent
+agent = Agent(
+ name="gemini_agent",
+ model=gemini,
+ instruction="You are a helpful assistant."
+)
+```
+
+---
+
+## Sessions
+
+### Session
+
+**Class**: `google.adk.sessions.Session`
+
+Represents a conversation session between a user and agents.
+
+#### Attributes
+
+- **session_id** (`str`): Unique session identifier
+- **user_id** (`str`): User identifier
+- **messages** (`list`): Conversation history
+- **state** (`dict`): Session state data
+
+### BaseSessionService
+
+**Class**: `google.adk.sessions.BaseSessionService`
+
+Abstract base class for session management services.
+
+#### Key Methods
+
+##### `get_session()`
+
+```python
+async def get_session(
+ self, *, app_name: str, user_id: str, session_id: str
+) -> Session
+```
+
+Retrieves or creates a session.
+
+##### `save_session()`
+
+```python
+async def save_session(self, *, session: Session) -> None
+```
+
+Persists session data.
+
+#### Implementations
+
+- **InMemorySessionService**: In-memory session storage
+- **DatabaseSessionService**: Database-backed session storage
+- **VertexAiSessionService**: Vertex AI-powered session storage
+
+#### Example Usage
+
+```python
+from google.adk.sessions import InMemorySessionService
+
+session_service = InMemorySessionService()
+
+# Use with runner
+runner = Runner(
+ app_name="my_app",
+ agent=agent,
+ session_service=session_service
+)
+```
+
+---
+
+## Examples
+
+### Example
+
+**Class**: `google.adk.examples.Example`
+
+Represents a training or evaluation example for agents.
+
+### BaseExampleProvider
+
+**Class**: `google.adk.examples.BaseExampleProvider`
+
+Abstract base class for providing examples to agents.
+
+### VertexAiExampleStore
+
+**Class**: `google.adk.examples.VertexAiExampleStore`
+
+Vertex AI-backed example storage service.
+
+---
+
+## Utilities
+
+### Feature Decorators
+
+```python
+from google.adk.utils.feature_decorator import experimental
+
+@experimental
+class MyExperimentalFeature:
+ pass
+
+@experimental
+def my_experimental_function():
+ pass
+```
+
+Mark features as experimental or work-in-progress.
+
+### Model Name Utilities
+
+```python
+from google.adk.utils.model_name_utils import extract_model_name, is_gemini_model
+
+model_name = extract_model_name("projects/my-project/locations/us/models/gemini-2.0-flash")
+is_gemini = is_gemini_model("gemini-2.0-flash")
+```
+
+Utilities for working with model names and identification.
+
+### Variant Utils
+
+```python
+from google.adk.utils.variant_utils import get_google_llm_variant, GoogleLLMVariant
+
+variant = get_google_llm_variant()
+```
+
+Utilities for working with Google LLM variants.
+
+---
+
+## Type Aliases and Callbacks
+
+### Callback Types
+
+```python
+from google.adk.agents.llm_agent import (
+ BeforeModelCallback,
+ AfterModelCallback,
+ BeforeToolCallback,
+ AfterToolCallback,
+ InstructionProvider
+)
+```
+
+Type aliases for various callback functions used throughout the framework.
+
+### Tool Types
+
+```python
+from google.adk.agents.llm_agent import ToolUnion
+```
+
+Union type for tools that can be functions, BaseTool instances, or BaseToolset instances.
+
+---
+
+## Error Handling
+
+The ADK framework includes custom exception classes for better error handling:
+
+```python
+from google.adk.errors import ADKError
+
+try:
+ # ADK operations
+ pass
+except ADKError as e:
+ print(f"ADK Error: {e}")
+```
+
+---
+
+This API reference provides comprehensive coverage of the Google ADK's public interfaces. For more detailed examples and tutorials, refer to the [User Guide](user-guide.md) and [Examples](examples.md) documentation.
\ No newline at end of file
diff --git a/docs/examples.md b/docs/examples.md
new file mode 100644
index 00000000000..ab868461a43
--- /dev/null
+++ b/docs/examples.md
@@ -0,0 +1,1053 @@
+# Google ADK Examples and Usage Guide
+
+This guide provides practical examples and usage patterns for building applications with the Google Agent Development Kit (ADK).
+
+## Table of Contents
+
+- [Getting Started](#getting-started)
+- [Basic Agent Examples](#basic-agent-examples)
+- [Multi-Agent Systems](#multi-agent-systems)
+- [Tool Integration](#tool-integration)
+- [Advanced Patterns](#advanced-patterns)
+- [Production Deployment](#production-deployment)
+- [Complete Applications](#complete-applications)
+
+---
+
+## Getting Started
+
+### Installation and Setup
+
+```bash
+# Install Google ADK
+pip install google-adk
+
+# For development version
+pip install git+https://github.com/google/adk-python.git@main
+```
+
+### Basic Environment Setup
+
+```python
+import os
+from google.adk import Agent, Runner
+from google.adk.sessions import InMemorySessionService
+
+# Set up environment (if needed)
+os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "path/to/credentials.json"
+```
+
+---
+
+## Basic Agent Examples
+
+### Simple Assistant
+
+```python
+from google.adk import Agent, Runner
+from google.adk.sessions import InMemorySessionService
+
+# Create a basic assistant
+assistant = Agent(
+ name="helpful_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a helpful assistant. Be concise and friendly.",
+)
+
+# Set up runner
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="simple_assistant",
+ agent=assistant,
+ session_service=session_service
+)
+
+# Run the assistant
+for event in runner.run(
+ user_id="user123",
+ session_id="session456",
+ new_message="Hello! Can you help me with Python programming?"
+):
+ if event.type == "model_response":
+ print(f"Assistant: {event.data.get('text', '')}")
+```
+
+### Search-Enabled Agent
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import google_search
+from google.adk.sessions import InMemorySessionService
+
+# Create search agent
+search_agent = Agent(
+ name="search_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a research assistant. Use web search to find current information and provide accurate, up-to-date answers.",
+ tools=[google_search]
+)
+
+# Setup and run
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="search_app",
+ agent=search_agent,
+ session_service=session_service
+)
+
+# Example interaction
+for event in runner.run(
+ user_id="researcher",
+ session_id="research_session",
+ new_message="What are the latest developments in quantum computing?"
+):
+ if event.type == "model_response":
+ print(f"Research Assistant: {event.data.get('text', '')}")
+```
+
+### Custom Function Tool Agent
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import FunctionTool
+from google.adk.sessions import InMemorySessionService
+import datetime
+import json
+
+def get_current_time(timezone: str = "UTC") -> dict:
+ """Get the current time in the specified timezone.
+
+ Args:
+ timezone: Timezone name (e.g., 'UTC', 'US/Eastern')
+
+ Returns:
+ Dictionary with current time information
+ """
+ now = datetime.datetime.now()
+ return {
+ "current_time": now.isoformat(),
+ "timezone": timezone,
+ "timestamp": now.timestamp(),
+ "formatted": now.strftime("%Y-%m-%d %H:%M:%S")
+ }
+
+def calculate_age(birth_year: int, current_year: int = None) -> dict:
+ """Calculate age from birth year.
+
+ Args:
+ birth_year: Year of birth
+ current_year: Current year (defaults to current year)
+
+ Returns:
+ Dictionary with age information
+ """
+ if current_year is None:
+ current_year = datetime.datetime.now().year
+
+ age = current_year - birth_year
+ return {
+ "age": age,
+ "birth_year": birth_year,
+ "current_year": current_year
+ }
+
+# Create tools from functions
+time_tool = FunctionTool(func=get_current_time)
+age_tool = FunctionTool(func=calculate_age)
+
+# Create agent with custom tools
+utility_agent = Agent(
+ name="utility_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a utility assistant with access to time and age calculation tools. Help users with these calculations.",
+ tools=[time_tool, age_tool]
+)
+
+# Example usage
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="utility_app",
+ agent=utility_agent,
+ session_service=session_service
+)
+
+for event in runner.run(
+ user_id="user",
+ session_id="util_session",
+ new_message="What time is it and calculate the age of someone born in 1990?"
+):
+ if event.type == "model_response":
+ print(f"Utility Assistant: {event.data.get('text', '')}")
+```
+
+---
+
+## Multi-Agent Systems
+
+### Research and Writing Pipeline
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import google_search, AgentTool
+from google.adk.sessions import InMemorySessionService
+
+# Create specialized agents
+researcher = Agent(
+ name="researcher",
+ model="gemini-2.0-flash",
+ instruction="""You are a research specialist. Your job is to:
+ 1. Search for current, accurate information on the given topic
+ 2. Gather facts, statistics, and key points
+ 3. Organize findings in a clear, structured format
+ 4. Provide sources and context for the information""",
+ tools=[google_search]
+)
+
+writer = Agent(
+ name="writer",
+ model="gemini-2.0-flash",
+ instruction="""You are a professional writer. Your job is to:
+ 1. Take research findings and create engaging content
+ 2. Structure information logically with clear headings
+ 3. Write in a clear, accessible style
+ 4. Include relevant examples and context
+ 5. Ensure the content flows well and is engaging"""
+)
+
+editor = Agent(
+ name="editor",
+ model="gemini-2.0-flash",
+ instruction="""You are an editor. Your job is to:
+ 1. Review written content for clarity and accuracy
+ 2. Check for grammatical errors and flow
+ 3. Suggest improvements for readability
+ 4. Ensure the content meets the original requirements
+ 5. Provide a polished final version"""
+)
+
+# Create tools from agents
+research_tool = AgentTool(agent=researcher)
+writing_tool = AgentTool(agent=writer)
+editing_tool = AgentTool(agent=editor)
+
+# Coordinator agent
+coordinator = Agent(
+ name="content_coordinator",
+ model="gemini-2.0-flash",
+ instruction="""You coordinate content creation. Follow this process:
+ 1. Use the research tool to gather information on the topic
+ 2. Use the writing tool to create content based on the research
+ 3. Use the editing tool to polish the final content
+ 4. Present the final polished content to the user""",
+ tools=[research_tool, writing_tool, editing_tool]
+)
+
+# Example usage
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="content_pipeline",
+ agent=coordinator,
+ session_service=session_service
+)
+
+for event in runner.run(
+ user_id="content_creator",
+ session_id="creation_session",
+ new_message="Create a comprehensive article about sustainable energy solutions"
+):
+ if event.type == "model_response":
+ print(f"Coordinator: {event.data.get('text', '')}")
+```
+
+### Customer Support System
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import AgentTool, FunctionTool
+from google.adk.sessions import InMemorySessionService
+
+# Simulated knowledge base
+KNOWLEDGE_BASE = {
+ "password_reset": "To reset your password, go to login page and click 'Forgot Password'",
+ "billing": "For billing questions, contact billing@company.com or call 1-800-BILLING",
+ "technical_support": "Technical issues can be reported at support@company.com",
+ "account_status": "Check account status in your user dashboard under Account Settings"
+}
+
+def search_knowledge_base(query: str) -> dict:
+ """Search the knowledge base for relevant information.
+
+ Args:
+ query: Search query
+
+ Returns:
+ Dictionary with search results
+ """
+ results = []
+ query_lower = query.lower()
+
+ for topic, content in KNOWLEDGE_BASE.items():
+ if any(word in topic.lower() or word in content.lower()
+ for word in query_lower.split()):
+ results.append({"topic": topic, "content": content})
+
+ return {"results": results, "query": query}
+
+def escalate_to_human(issue: str, priority: str = "normal") -> dict:
+ """Escalate issue to human support.
+
+ Args:
+ issue: Description of the issue
+ priority: Priority level (low, normal, high, urgent)
+
+ Returns:
+ Escalation ticket information
+ """
+ ticket_id = f"TICKET-{hash(issue) % 10000:04d}"
+ return {
+ "ticket_id": ticket_id,
+ "issue": issue,
+ "priority": priority,
+ "status": "escalated",
+ "message": f"Your issue has been escalated to human support. Ticket ID: {ticket_id}"
+ }
+
+# Create specialized agents
+knowledge_agent = Agent(
+ name="knowledge_assistant",
+ model="gemini-2.0-flash",
+ instruction="Search the knowledge base and provide helpful information to users.",
+ tools=[FunctionTool(func=search_knowledge_base)]
+)
+
+escalation_agent = Agent(
+ name="escalation_handler",
+ model="gemini-2.0-flash",
+ instruction="Handle escalations to human support when issues cannot be resolved automatically.",
+ tools=[FunctionTool(func=escalate_to_human)]
+)
+
+# Main support agent
+support_agent = Agent(
+ name="support_coordinator",
+ model="gemini-2.0-flash",
+ instruction="""You are a customer support coordinator. Follow this process:
+ 1. Understand the customer's issue clearly
+ 2. Try to resolve using the knowledge base first
+ 3. If the issue cannot be resolved, escalate to human support
+ 4. Always be helpful, patient, and professional
+ 5. Provide clear next steps to the customer""",
+ tools=[
+ AgentTool(agent=knowledge_agent),
+ AgentTool(agent=escalation_agent)
+ ]
+)
+
+# Example usage
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="customer_support",
+ agent=support_agent,
+ session_service=session_service
+)
+
+for event in runner.run(
+ user_id="customer123",
+ session_id="support_session",
+ new_message="I can't reset my password and I need urgent help with my billing"
+):
+ if event.type == "model_response":
+ print(f"Support: {event.data.get('text', '')}")
+```
+
+---
+
+## Tool Integration
+
+### REST API Integration
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import BaseTool, ToolContext
+from google.adk.sessions import InMemorySessionService
+import aiohttp
+import json
+from typing import Any, Optional
+from google.genai import types
+
+class WeatherAPITool(BaseTool):
+ """Tool for fetching weather data from an API."""
+
+ def __init__(self, api_key: str):
+ super().__init__(
+ name="weather_api",
+ description="Get current weather information for any city"
+ )
+ self.api_key = api_key
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ city = args.get("city")
+ if not city:
+ return {"error": "City name is required"}
+
+ # Simulate API call (replace with real API)
+ async with aiohttp.ClientSession() as session:
+ # In a real implementation, you would make an actual API call
+ # url = f"https://api.weather.com/v1/current?city={city}&key={self.api_key}"
+ # async with session.get(url) as response:
+ # data = await response.json()
+ # return data
+
+ # Simulated response
+ return {
+ "city": city,
+ "temperature": "22°C",
+ "condition": "Sunny",
+ "humidity": "45%",
+ "wind_speed": "10 km/h"
+ }
+
+ def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
+ return types.FunctionDeclaration(
+ name=self.name,
+ description=self.description,
+ parameters=types.Schema(
+ type=types.Type.OBJECT,
+ properties={
+ "city": types.Schema(
+ type=types.Type.STRING,
+ description="The city name to get weather for"
+ )
+ },
+ required=["city"]
+ )
+ )
+
+# Create weather agent
+weather_tool = WeatherAPITool(api_key="your-api-key")
+
+weather_agent = Agent(
+ name="weather_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a weather assistant. Use the weather API to provide current weather information for any city requested.",
+ tools=[weather_tool]
+)
+
+# Example usage
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="weather_app",
+ agent=weather_agent,
+ session_service=session_service
+)
+
+for event in runner.run(
+ user_id="user",
+ session_id="weather_session",
+ new_message="What's the weather like in Tokyo?"
+):
+ if event.type == "model_response":
+ print(f"Weather Assistant: {event.data.get('text', '')}")
+```
+
+### Database Integration
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import FunctionTool
+from google.adk.sessions import InMemorySessionService
+import sqlite3
+import json
+from typing import List, Dict, Any
+
+# Set up a simple database
+def setup_database():
+ """Set up a simple user database for demonstration."""
+ conn = sqlite3.connect(":memory:")
+ cursor = conn.cursor()
+
+ # Create users table
+ cursor.execute("""
+ CREATE TABLE users (
+ id INTEGER PRIMARY KEY,
+ name TEXT NOT NULL,
+ email TEXT UNIQUE NOT NULL,
+ age INTEGER,
+ city TEXT
+ )
+ """)
+
+ # Insert sample data
+ users = [
+ (1, "Alice Johnson", "alice@example.com", 30, "New York"),
+ (2, "Bob Smith", "bob@example.com", 25, "Los Angeles"),
+ (3, "Carol Davis", "carol@example.com", 35, "Chicago"),
+ (4, "David Wilson", "david@example.com", 28, "Houston")
+ ]
+
+ cursor.executemany("INSERT INTO users VALUES (?, ?, ?, ?, ?)", users)
+ conn.commit()
+ return conn
+
+# Database connection
+db_conn = setup_database()
+
+def search_users(name: str = None, city: str = None, min_age: int = None) -> List[Dict[str, Any]]:
+ """Search users in the database.
+
+ Args:
+ name: Name to search for (partial match)
+ city: City to filter by
+ min_age: Minimum age filter
+
+ Returns:
+ List of matching users
+ """
+ cursor = db_conn.cursor()
+ query = "SELECT id, name, email, age, city FROM users WHERE 1=1"
+ params = []
+
+ if name:
+ query += " AND name LIKE ?"
+ params.append(f"%{name}%")
+
+ if city:
+ query += " AND city = ?"
+ params.append(city)
+
+ if min_age is not None:
+ query += " AND age >= ?"
+ params.append(min_age)
+
+ cursor.execute(query, params)
+ results = cursor.fetchall()
+
+ return [
+ {
+ "id": row[0],
+ "name": row[1],
+ "email": row[2],
+ "age": row[3],
+ "city": row[4]
+ }
+ for row in results
+ ]
+
+def get_user_count_by_city() -> Dict[str, int]:
+ """Get count of users by city.
+
+ Returns:
+ Dictionary with city names and user counts
+ """
+ cursor = db_conn.cursor()
+ cursor.execute("SELECT city, COUNT(*) FROM users GROUP BY city")
+ results = cursor.fetchall()
+
+ return {city: count for city, count in results}
+
+# Create database tools
+search_tool = FunctionTool(func=search_users)
+stats_tool = FunctionTool(func=get_user_count_by_city)
+
+# Create database agent
+db_agent = Agent(
+ name="database_assistant",
+ model="gemini-2.0-flash",
+ instruction="""You are a database assistant. You can help users search for users and get statistics from the user database.
+ Use the search_users function to find specific users and get_user_count_by_city to get statistics.""",
+ tools=[search_tool, stats_tool]
+)
+
+# Example usage
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="database_app",
+ agent=db_agent,
+ session_service=session_service
+)
+
+for event in runner.run(
+ user_id="admin",
+ session_id="db_session",
+ new_message="Find all users in New York and show me user statistics by city"
+):
+ if event.type == "model_response":
+ print(f"Database Assistant: {event.data.get('text', '')}")
+```
+
+---
+
+## Advanced Patterns
+
+### Async Operations and Streaming
+
+```python
+import asyncio
+from google.adk import Agent, Runner
+from google.adk.tools import BaseTool, ToolContext
+from google.adk.sessions import InMemorySessionService
+from typing import Any, AsyncGenerator
+
+class StreamingDataTool(BaseTool):
+ """Tool that demonstrates streaming data processing."""
+
+ def __init__(self):
+ super().__init__(
+ name="streaming_processor",
+ description="Process data in streaming fashion",
+ is_long_running=True
+ )
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ data_type = args.get("data_type", "numbers")
+ count = args.get("count", 10)
+
+ results = []
+
+ # Simulate streaming processing
+ for i in range(count):
+ if data_type == "numbers":
+ item = {"index": i, "value": i * i, "timestamp": i}
+ else:
+ item = {"index": i, "message": f"Processed item {i}", "timestamp": i}
+
+ results.append(item)
+
+ # Simulate processing delay
+ await asyncio.sleep(0.1)
+
+ # In a real streaming scenario, you might yield results progressively
+ # For this example, we collect all results
+
+ return {
+ "data_type": data_type,
+ "total_processed": len(results),
+ "results": results[:5], # Return first 5 for brevity
+ "summary": f"Processed {len(results)} items of type {data_type}"
+ }
+
+# Callback functions for monitoring
+async def before_tool_callback(tool, args, tool_context):
+ """Called before tool execution."""
+ print(f"Starting tool: {tool.name} with args: {args}")
+ return None
+
+async def after_tool_callback(tool, args, tool_context, result):
+ """Called after tool execution."""
+ print(f"Completed tool: {tool.name}")
+ return None
+
+# Create streaming agent with callbacks
+streaming_agent = Agent(
+ name="streaming_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a streaming data processor. Use the streaming tool to process data requests.",
+ tools=[StreamingDataTool()],
+ before_tool_callbacks=before_tool_callback,
+ after_tool_callbacks=after_tool_callback
+)
+
+async def run_streaming_example():
+ """Run the streaming example asynchronously."""
+ session_service = InMemorySessionService()
+ runner = Runner(
+ app_name="streaming_app",
+ agent=streaming_agent,
+ session_service=session_service
+ )
+
+ async for event in runner.run_async(
+ user_id="stream_user",
+ session_id="stream_session",
+ new_message="Process 20 numbers in streaming fashion"
+ ):
+ if event.type == "model_response":
+ print(f"Streaming Assistant: {event.data.get('text', '')}")
+
+# Run the async example
+# asyncio.run(run_streaming_example())
+```
+
+### State Management and Memory
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import FunctionTool, load_memory, preload_memory
+from google.adk.sessions import InMemorySessionService
+from google.adk.memory import InMemoryMemoryService
+
+# State management functions
+def save_user_preference(key: str, value: str, user_context: dict = None) -> dict:
+ """Save a user preference.
+
+ Args:
+ key: Preference key
+ value: Preference value
+ user_context: Current user context
+
+ Returns:
+ Confirmation of saved preference
+ """
+ # In a real implementation, this would save to a database
+ print(f"Saving preference: {key} = {value}")
+ return {
+ "saved": True,
+ "key": key,
+ "value": value,
+ "message": f"Preference '{key}' saved as '{value}'"
+ }
+
+def get_user_preference(key: str, user_context: dict = None) -> dict:
+ """Get a user preference.
+
+ Args:
+ key: Preference key to retrieve
+ user_context: Current user context
+
+ Returns:
+ The preference value or default
+ """
+ # Simulated preferences store
+ preferences = {
+ "theme": "dark",
+ "language": "en",
+ "notifications": "enabled"
+ }
+
+ value = preferences.get(key, "not_set")
+ return {
+ "key": key,
+ "value": value,
+ "found": key in preferences
+ }
+
+# Create stateful agent
+stateful_agent = Agent(
+ name="stateful_assistant",
+ model="gemini-2.0-flash",
+ instruction="""You are a stateful assistant that remembers user preferences and conversation history.
+ You can save and retrieve user preferences, and you maintain context across conversations.
+ Always use the conversation memory to provide personalized responses.""",
+ tools=[
+ FunctionTool(func=save_user_preference),
+ FunctionTool(func=get_user_preference),
+ load_memory,
+ preload_memory
+ ]
+)
+
+# Set up with memory service
+session_service = InMemorySessionService()
+memory_service = InMemoryMemoryService()
+
+runner = Runner(
+ app_name="stateful_app",
+ agent=stateful_agent,
+ session_service=session_service,
+ memory_service=memory_service
+)
+
+# Example conversation with state
+print("=== First interaction ===")
+for event in runner.run(
+ user_id="stateful_user",
+ session_id="persistent_session",
+ new_message="Hi! I prefer dark theme and want notifications enabled. Please save these preferences."
+):
+ if event.type == "model_response":
+ print(f"Assistant: {event.data.get('text', '')}")
+
+print("\n=== Second interaction (same session) ===")
+for event in runner.run(
+ user_id="stateful_user",
+ session_id="persistent_session",
+ new_message="What were my theme preferences again?"
+):
+ if event.type == "model_response":
+ print(f"Assistant: {event.data.get('text', '')}")
+```
+
+---
+
+## Production Deployment
+
+### FastAPI Web Service
+
+```python
+from fastapi import FastAPI, HTTPException
+from pydantic import BaseModel
+from google.adk import Agent, Runner
+from google.adk.tools import google_search
+from google.adk.sessions import InMemorySessionService
+import asyncio
+import uuid
+from typing import Optional
+
+app = FastAPI(title="ADK Agent Service", version="1.0.0")
+
+# Request/Response models
+class ChatRequest(BaseModel):
+ message: str
+ user_id: Optional[str] = None
+ session_id: Optional[str] = None
+
+class ChatResponse(BaseModel):
+ response: str
+ user_id: str
+ session_id: str
+
+# Initialize agent and runner
+agent = Agent(
+ name="web_assistant",
+ model="gemini-2.0-flash",
+ instruction="You are a helpful web assistant. Provide clear, concise responses.",
+ tools=[google_search]
+)
+
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="web_service",
+ agent=agent,
+ session_service=session_service
+)
+
+@app.post("/chat", response_model=ChatResponse)
+async def chat(request: ChatRequest):
+ """Chat endpoint for interacting with the agent."""
+ try:
+ user_id = request.user_id or str(uuid.uuid4())
+ session_id = request.session_id or str(uuid.uuid4())
+
+ response_text = ""
+
+ async for event in runner.run_async(
+ user_id=user_id,
+ session_id=session_id,
+ new_message=request.message
+ ):
+ if event.type == "model_response":
+ response_text = event.data.get("text", "")
+ break
+
+ return ChatResponse(
+ response=response_text,
+ user_id=user_id,
+ session_id=session_id
+ )
+
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+@app.get("/health")
+async def health_check():
+ """Health check endpoint."""
+ return {"status": "healthy", "service": "adk-agent-service"}
+
+if __name__ == "__main__":
+ import uvicorn
+ uvicorn.run(app, host="0.0.0.0", port=8000)
+```
+
+### Docker Deployment
+
+```dockerfile
+# Dockerfile
+FROM python:3.11-slim
+
+WORKDIR /app
+
+# Install dependencies
+COPY requirements.txt .
+RUN pip install --no-cache-dir -r requirements.txt
+
+# Copy application code
+COPY . .
+
+# Expose port
+EXPOSE 8000
+
+# Run the application
+CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
+```
+
+```yaml
+# docker-compose.yml
+version: '3.8'
+
+services:
+ adk-agent:
+ build: .
+ ports:
+ - "8000:8000"
+ environment:
+ - GOOGLE_APPLICATION_CREDENTIALS=/app/credentials.json
+ volumes:
+ - ./credentials.json:/app/credentials.json:ro
+ restart: unless-stopped
+
+ redis:
+ image: redis:alpine
+ ports:
+ - "6379:6379"
+ restart: unless-stopped
+```
+
+---
+
+## Complete Applications
+
+### Personal Assistant Bot
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import (
+ google_search, url_context, FunctionTool,
+ load_memory, preload_memory
+)
+from google.adk.sessions import InMemorySessionService
+from google.adk.memory import InMemoryMemoryService
+import datetime
+import json
+
+# Personal assistant functions
+def create_reminder(task: str, date: str, time: str = "09:00") -> dict:
+ """Create a reminder for a task.
+
+ Args:
+ task: Task description
+ date: Date in YYYY-MM-DD format
+ time: Time in HH:MM format
+
+ Returns:
+ Reminder confirmation
+ """
+ reminder_id = f"REM_{hash(f'{task}{date}{time}') % 10000:04d}"
+ return {
+ "reminder_id": reminder_id,
+ "task": task,
+ "date": date,
+ "time": time,
+ "status": "created",
+ "message": f"Reminder created: '{task}' on {date} at {time}"
+ }
+
+def get_calendar_events(date: str = None) -> dict:
+ """Get calendar events for a specific date.
+
+ Args:
+ date: Date in YYYY-MM-DD format (defaults to today)
+
+ Returns:
+ List of events for the date
+ """
+ if not date:
+ date = datetime.date.today().isoformat()
+
+ # Simulated calendar events
+ events = {
+ "2024-01-15": [
+ {"time": "09:00", "title": "Team Meeting", "duration": "1h"},
+ {"time": "14:00", "title": "Project Review", "duration": "30m"}
+ ],
+ "2024-01-16": [
+ {"time": "10:00", "title": "Client Call", "duration": "45m"}
+ ]
+ }
+
+ return {
+ "date": date,
+ "events": events.get(date, []),
+ "total_events": len(events.get(date, []))
+ }
+
+def calculate_distance(origin: str, destination: str) -> dict:
+ """Calculate distance between two locations.
+
+ Args:
+ origin: Starting location
+ destination: Ending location
+
+ Returns:
+ Distance and travel time information
+ """
+ # Simulated distance calculation
+ return {
+ "origin": origin,
+ "destination": destination,
+ "distance": "25.3 km",
+ "driving_time": "32 minutes",
+ "walking_time": "4 hours 15 minutes",
+ "public_transport": "45 minutes"
+ }
+
+# Create personal assistant
+personal_assistant = Agent(
+ name="personal_assistant",
+ model="gemini-2.0-flash",
+ instruction="""You are a comprehensive personal assistant. You can help with:
+
+ 1. Information research and web searches
+ 2. Creating reminders and managing tasks
+ 3. Checking calendar events and scheduling
+ 4. Calculating distances and travel times
+ 5. Analyzing web content and URLs
+ 6. Maintaining conversation context and memory
+
+ Always be proactive, helpful, and personalized in your responses.
+ Use the available tools to provide accurate and useful information.""",
+ tools=[
+ google_search,
+ url_context,
+ FunctionTool(func=create_reminder),
+ FunctionTool(func=get_calendar_events),
+ FunctionTool(func=calculate_distance),
+ load_memory,
+ preload_memory
+ ]
+)
+
+# Set up services
+session_service = InMemorySessionService()
+memory_service = InMemoryMemoryService()
+
+runner = Runner(
+ app_name="personal_assistant",
+ agent=personal_assistant,
+ session_service=session_service,
+ memory_service=memory_service
+)
+
+# Example interactions
+def run_personal_assistant_demo():
+ """Run a demo of the personal assistant."""
+
+ interactions = [
+ "Hi! I'm planning a trip to Tokyo next week. Can you help me research the best places to visit?",
+ "Great! Can you also create a reminder for me to book flights on January 20th at 2 PM?",
+ "What's the distance between Tokyo Station and Shibuya?",
+ "Check my calendar for January 15th and 16th.",
+ "Can you search for current weather in Tokyo?"
+ ]
+
+ user_id = "demo_user"
+ session_id = "demo_session"
+
+ for i, message in enumerate(interactions, 1):
+ print(f"\n=== Interaction {i} ===")
+ print(f"User: {message}")
+
+ for event in runner.run(
+ user_id=user_id,
+ session_id=session_id,
+ new_message=message
+ ):
+ if event.type == "model_response":
+ print(f"Assistant: {event.data.get('text', '')}")
+
+# Uncomment to run the demo
+# run_personal_assistant_demo()
+```
+
+---
+
+This examples guide demonstrates the flexibility and power of the Google ADK framework. From simple assistants to complex multi-agent systems, ADK provides the tools and patterns needed to build sophisticated AI applications.
\ No newline at end of file
diff --git a/docs/tools-guide.md b/docs/tools-guide.md
new file mode 100644
index 00000000000..a7000f452bd
--- /dev/null
+++ b/docs/tools-guide.md
@@ -0,0 +1,649 @@
+# Google ADK Tools Guide
+
+This guide provides comprehensive documentation for all tools available in the Google Agent Development Kit (ADK), including built-in tools, custom tool creation, and integration patterns.
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Built-in Tools](#built-in-tools)
+ - [Search Tools](#search-tools)
+ - [Utility Tools](#utility-tools)
+ - [Integration Tools](#integration-tools)
+ - [Memory and Artifact Tools](#memory-and-artifact-tools)
+- [Custom Tool Development](#custom-tool-development)
+- [Tool Configuration](#tool-configuration)
+- [Best Practices](#best-practices)
+
+---
+
+## Overview
+
+Tools in ADK extend agent capabilities by providing access to external services, APIs, functions, and data sources. The framework supports multiple tool types:
+
+1. **Built-in Tools**: Pre-implemented tools for common tasks
+2. **Function Tools**: Python functions wrapped as tools
+3. **Custom Tools**: Tools extending `BaseTool` for complex logic
+4. **OpenAPI Tools**: REST API endpoints exposed as tools
+5. **Agent Tools**: Other agents used as tools
+6. **Toolsets**: Collections of related tools
+
+---
+
+## Built-in Tools
+
+### Search Tools
+
+#### Google Search
+
+**Import**: `from google.adk.tools import google_search`
+
+Built-in Google Search integration for Gemini models.
+
+```python
+from google.adk import Agent
+from google.adk.tools import google_search
+
+agent = Agent(
+ name="search_agent",
+ model="gemini-2.0-flash",
+ instruction="Search the web to answer user questions.",
+ tools=[google_search]
+)
+```
+
+**Features:**
+- Automatic integration with Gemini 2.0+ models
+- No API keys required
+- Built-in result formatting
+- Optimized for conversational search
+
+**Limitations:**
+- Only works with Gemini models
+- Cannot be combined with other tools in Gemini 1.x models
+
+#### Enterprise Search
+
+**Import**: `from google.adk.tools import enterprise_web_search`
+
+Search within enterprise content using Google Enterprise Search.
+
+```python
+from google.adk.tools import enterprise_web_search
+
+enterprise_agent = Agent(
+ name="enterprise_assistant",
+ model="gemini-2.0-flash",
+ instruction="Help users find information from company resources.",
+ tools=[enterprise_web_search]
+)
+```
+
+**Use Cases:**
+- Internal knowledge base search
+- Company document retrieval
+- Enterprise content discovery
+
+#### Vertex AI Search
+
+**Class**: `google.adk.tools.VertexAiSearchTool`
+
+Custom search using Vertex AI Search service.
+
+```python
+from google.adk.tools import VertexAiSearchTool
+
+search_tool = VertexAiSearchTool(
+ project_id="your-project",
+ location="us-central1",
+ data_store_id="your-datastore"
+)
+
+agent = Agent(
+ name="custom_search_agent",
+ model="gemini-2.0-flash",
+ tools=[search_tool]
+)
+```
+
+### Utility Tools
+
+#### Function Tool
+
+**Class**: `google.adk.tools.FunctionTool`
+
+Wraps Python functions as tools for agent use.
+
+```python
+from google.adk.tools import FunctionTool
+
+def calculate_tip(bill_amount: float, tip_percentage: float = 15.0) -> dict:
+ """Calculate tip amount and total bill.
+
+ Args:
+ bill_amount: The original bill amount
+ tip_percentage: Tip percentage (default: 15.0)
+
+ Returns:
+ Dictionary with tip amount and total
+ """
+ tip_amount = bill_amount * (tip_percentage / 100)
+ total = bill_amount + tip_amount
+ return {
+ "tip_amount": round(tip_amount, 2),
+ "total": round(total, 2),
+ "tip_percentage": tip_percentage
+ }
+
+# Create tool from function
+tip_calculator = FunctionTool(func=calculate_tip)
+
+# Use in agent
+agent = Agent(
+ name="tip_calculator",
+ model="gemini-2.0-flash",
+ instruction="Help users calculate tips and totals.",
+ tools=[tip_calculator]
+)
+```
+
+**Function Requirements:**
+- Type hints for parameters (recommended)
+- Docstring describing functionality
+- JSON-serializable return values
+- No side effects that affect tool context
+
+#### URL Context Tool
+
+**Import**: `from google.adk.tools import url_context`
+
+Extracts and analyzes content from web URLs.
+
+```python
+from google.adk.tools import url_context
+
+web_agent = Agent(
+ name="web_analyzer",
+ model="gemini-2.0-flash",
+ instruction="Analyze web pages and answer questions about their content.",
+ tools=[url_context]
+)
+```
+
+**Capabilities:**
+- HTML content extraction
+- Text summarization
+- Link analysis
+- Metadata extraction
+
+#### Exit Loop Tool
+
+**Import**: `from google.adk.tools import exit_loop`
+
+Provides a way to exit loops in agent workflows.
+
+```python
+from google.adk.tools import exit_loop
+from google.adk.agents import LoopAgent
+
+loop_agent = LoopAgent(
+ name="task_loop",
+ model="gemini-2.0-flash",
+ instruction="Process tasks in a loop. Use exit_loop when done.",
+ tools=[exit_loop]
+)
+```
+
+#### User Choice Tool
+
+**Import**: `from google.adk.tools import get_user_choice`
+
+Allows agents to present choices to users and get their selection.
+
+```python
+from google.adk.tools import get_user_choice
+
+interactive_agent = Agent(
+ name="choice_agent",
+ model="gemini-2.0-flash",
+ instruction="Present options to users and get their preferences.",
+ tools=[get_user_choice]
+)
+```
+
+### Integration Tools
+
+#### Agent Tool
+
+**Class**: `google.adk.tools.AgentTool`
+
+Enables agents to invoke other agents as tools.
+
+```python
+from google.adk.tools import AgentTool
+
+# Create specialized agents
+researcher = Agent(
+ name="researcher",
+ model="gemini-2.0-flash",
+ instruction="Research topics and gather information.",
+ tools=[google_search]
+)
+
+writer = Agent(
+ name="writer",
+ model="gemini-2.0-flash",
+ instruction="Write clear, engaging content based on research."
+)
+
+# Create tools from agents
+research_tool = AgentTool(agent=researcher)
+writing_tool = AgentTool(agent=writer)
+
+# Coordinator agent using other agents as tools
+coordinator = Agent(
+ name="coordinator",
+ model="gemini-2.0-flash",
+ instruction="Coordinate research and writing tasks.",
+ tools=[research_tool, writing_tool]
+)
+```
+
+**Benefits:**
+- Modular agent composition
+- Reusable specialized agents
+- Clear separation of concerns
+- Hierarchical agent structures
+
+#### OpenAPI Tool
+
+**Package**: `google.adk.tools.openapi_tool`
+
+Automatically generates tools from OpenAPI specifications.
+
+```python
+from google.adk.tools.openapi_tool import create_openapi_tools
+
+# Create tools from OpenAPI spec
+api_tools = create_openapi_tools(
+ openapi_spec_url="https://api.example.com/openapi.json",
+ base_url="https://api.example.com",
+ headers={"Authorization": "Bearer your-token"}
+)
+
+agent = Agent(
+ name="api_agent",
+ model="gemini-2.0-flash",
+ instruction="Interact with the API to fulfill user requests.",
+ tools=api_tools
+)
+```
+
+#### BigQuery Tool
+
+**Package**: `google.adk.tools.bigquery`
+
+Execute SQL queries against BigQuery datasets.
+
+```python
+from google.adk.tools.bigquery import BigQueryTool
+
+bq_tool = BigQueryTool(
+ project_id="your-project",
+ credentials_path="path/to/credentials.json"
+)
+
+data_agent = Agent(
+ name="data_analyst",
+ model="gemini-2.0-flash",
+ instruction="Answer questions by querying BigQuery datasets.",
+ tools=[bq_tool]
+)
+```
+
+#### MCP (Model Context Protocol) Tools
+
+**Class**: `google.adk.tools.MCPToolset` (Python 3.10+)
+
+Integrate MCP-compatible tools and services.
+
+```python
+from google.adk.tools import MCPToolset
+
+mcp_toolset = MCPToolset(
+ server_config={
+ "command": "python",
+ "args": ["-m", "mcp_server"],
+ "env": {}
+ }
+)
+
+agent = Agent(
+ name="mcp_agent",
+ model="gemini-2.0-flash",
+ instruction="Use MCP tools to assist users.",
+ tools=[mcp_toolset]
+)
+```
+
+### Memory and Artifact Tools
+
+#### Load Memory Tool
+
+**Import**: `from google.adk.tools import load_memory`
+
+Loads conversation memory into the current context.
+
+```python
+from google.adk.tools import load_memory
+
+memory_agent = Agent(
+ name="memory_agent",
+ model="gemini-2.0-flash",
+ instruction="Use conversation history to provide contextual responses.",
+ tools=[load_memory]
+)
+```
+
+#### Preload Memory Tool
+
+**Import**: `from google.adk.tools import preload_memory`
+
+Preloads memory at the start of conversations.
+
+```python
+from google.adk.tools import preload_memory
+
+contextual_agent = Agent(
+ name="contextual_agent",
+ model="gemini-2.0-flash",
+ instruction="Always maintain conversation context.",
+ tools=[preload_memory]
+)
+```
+
+#### Load Artifacts Tool
+
+**Import**: `from google.adk.tools import load_artifacts`
+
+Loads and manages artifacts (files, documents, data).
+
+```python
+from google.adk.tools import load_artifacts
+
+document_agent = Agent(
+ name="document_agent",
+ model="gemini-2.0-flash",
+ instruction="Work with documents and files provided by users.",
+ tools=[load_artifacts]
+)
+```
+
+---
+
+## Custom Tool Development
+
+### Creating a Basic Custom Tool
+
+```python
+from google.adk.tools import BaseTool, ToolContext
+from typing import Any, Optional
+from google.genai import types
+
+class WeatherTool(BaseTool):
+ """Custom weather information tool."""
+
+ def __init__(self, api_key: str):
+ super().__init__(
+ name="weather_tool",
+ description="Get current weather information for a given location",
+ )
+ self.api_key = api_key
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ location = args.get("location")
+ if not location:
+ return {"error": "Location is required"}
+
+ # Simulate API call
+ weather_data = {
+ "location": location,
+ "temperature": "22°C",
+ "condition": "Sunny",
+ "humidity": "45%"
+ }
+
+ return weather_data
+
+ def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
+ return types.FunctionDeclaration(
+ name=self.name,
+ description=self.description,
+ parameters=types.Schema(
+ type=types.Type.OBJECT,
+ properties={
+ "location": types.Schema(
+ type=types.Type.STRING,
+ description="The location to get weather for"
+ )
+ },
+ required=["location"]
+ )
+ )
+
+# Usage
+weather_tool = WeatherTool(api_key="your-api-key")
+
+agent = Agent(
+ name="weather_agent",
+ model="gemini-2.0-flash",
+ instruction="Provide weather information using the weather tool.",
+ tools=[weather_tool]
+)
+```
+
+### Advanced Custom Tool with Streaming
+
+```python
+from google.adk.tools import BaseTool, ToolContext
+from typing import Any, AsyncGenerator
+
+class StreamingDataTool(BaseTool):
+ """Tool that streams data progressively."""
+
+ def __init__(self):
+ super().__init__(
+ name="streaming_data",
+ description="Streams large datasets progressively",
+ is_long_running=True
+ )
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ query = args.get("query", "")
+
+ # Simulate streaming data
+ async def stream_data():
+ for i in range(5):
+ yield f"Data chunk {i+1} for query: {query}\n"
+ await asyncio.sleep(0.5) # Simulate processing time
+
+ result = ""
+ async for chunk in stream_data():
+ result += chunk
+
+ return {"data": result, "total_chunks": 5}
+```
+
+### Custom Tool with Authentication
+
+```python
+from google.adk.tools import BaseAuthenticatedTool
+from google.adk.auth import AuthToolArguments
+
+class AuthenticatedAPITool(BaseAuthenticatedTool):
+ """Tool requiring authentication."""
+
+ def __init__(self):
+ super().__init__(
+ name="authenticated_api",
+ description="Access authenticated API endpoints",
+ auth_args=AuthToolArguments(
+ service_name="example_api",
+ scopes=["https://www.example.com/auth/api"]
+ )
+ )
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ # Access authenticated resources
+ credentials = self.get_credentials(tool_context)
+
+ # Make authenticated API call
+ response = await self.make_authenticated_request(
+ url="https://api.example.com/data",
+ headers={"Authorization": f"Bearer {credentials.token}"},
+ params=args
+ )
+
+ return response
+```
+
+---
+
+## Tool Configuration
+
+### Tool Args Configuration
+
+```python
+from google.adk.tools.tool_configs import ToolConfig, ToolArgsConfig
+
+# Configure tool with specific arguments
+tool_config = ToolConfig(
+ name="custom_tool",
+ config=ToolArgsConfig(
+ custom_arg1="value1",
+ custom_arg2="value2"
+ )
+)
+
+# Use in agent configuration
+agent = Agent(
+ name="configured_agent",
+ model="gemini-2.0-flash",
+ tools=[tool_config]
+)
+```
+
+### Toolset Creation
+
+```python
+from google.adk.tools import BaseToolset, BaseTool
+
+class CalculationToolset(BaseToolset):
+ """Toolset for mathematical calculations."""
+
+ def __init__(self):
+ super().__init__(
+ name="calculation_toolset",
+ description="Mathematical calculation tools"
+ )
+
+ async def get_tools(self, ctx) -> list[BaseTool]:
+ return [
+ FunctionTool(func=self.add),
+ FunctionTool(func=self.multiply),
+ FunctionTool(func=self.divide)
+ ]
+
+ def add(self, a: float, b: float) -> float:
+ """Add two numbers."""
+ return a + b
+
+ def multiply(self, a: float, b: float) -> float:
+ """Multiply two numbers."""
+ return a * b
+
+ def divide(self, a: float, b: float) -> float:
+ """Divide two numbers."""
+ if b == 0:
+ raise ValueError("Cannot divide by zero")
+ return a / b
+
+# Usage
+calc_toolset = CalculationToolset()
+
+agent = Agent(
+ name="math_agent",
+ model="gemini-2.0-flash",
+ instruction="Perform mathematical calculations.",
+ tools=[calc_toolset]
+)
+```
+
+---
+
+## Best Practices
+
+### Tool Design
+
+1. **Single Responsibility**: Each tool should have one clear purpose
+2. **Descriptive Names**: Use clear, descriptive names and descriptions
+3. **Error Handling**: Implement robust error handling and validation
+4. **Type Safety**: Use type hints and validate inputs
+5. **Documentation**: Provide comprehensive docstrings
+
+### Performance Optimization
+
+1. **Async Operations**: Use async/await for I/O operations
+2. **Caching**: Implement caching for expensive operations
+3. **Resource Management**: Properly manage connections and resources
+4. **Timeouts**: Set appropriate timeouts for external calls
+
+### Security Considerations
+
+1. **Input Validation**: Validate all inputs thoroughly
+2. **Authentication**: Use proper authentication mechanisms
+3. **Rate Limiting**: Implement rate limiting for API calls
+4. **Data Sanitization**: Sanitize outputs to prevent injection attacks
+
+### Testing Tools
+
+```python
+import pytest
+from google.adk.tools import ToolContext
+from your_module import WeatherTool
+
+@pytest.mark.asyncio
+async def test_weather_tool():
+ tool = WeatherTool(api_key="test-key")
+ context = ToolContext(session_id="test", user_id="test-user")
+
+ result = await tool.run_async(
+ args={"location": "New York"},
+ tool_context=context
+ )
+
+ assert "location" in result
+ assert result["location"] == "New York"
+ assert "temperature" in result
+```
+
+### Tool Composition
+
+```python
+# Combine multiple tools effectively
+comprehensive_agent = Agent(
+ name="comprehensive_assistant",
+ model="gemini-2.0-flash",
+ instruction="Help users with various tasks using available tools.",
+ tools=[
+ google_search, # Web search
+ url_context, # Web page analysis
+ FunctionTool(func=calculate_tip), # Custom calculations
+ load_memory, # Memory management
+ weather_tool, # Custom weather info
+ ]
+)
+```
+
+---
+
+This tools guide provides comprehensive documentation for using and creating tools in the Google ADK framework. Tools are the primary way to extend agent capabilities and integrate with external services and data sources.
\ No newline at end of file
diff --git a/docs/user-guide.md b/docs/user-guide.md
new file mode 100644
index 00000000000..af43d48a902
--- /dev/null
+++ b/docs/user-guide.md
@@ -0,0 +1,927 @@
+# Google ADK User Guide
+
+Welcome to the Google Agent Development Kit (ADK)! This guide will help you get started with building AI agents, from basic concepts to advanced multi-agent systems.
+
+## Table of Contents
+
+- [What is Google ADK?](#what-is-google-adk)
+- [Installation and Setup](#installation-and-setup)
+- [Core Concepts](#core-concepts)
+- [Your First Agent](#your-first-agent)
+- [Working with Tools](#working-with-tools)
+- [Multi-Agent Systems](#multi-agent-systems)
+- [Advanced Features](#advanced-features)
+- [Best Practices](#best-practices)
+- [Troubleshooting](#troubleshooting)
+
+---
+
+## What is Google ADK?
+
+The Google Agent Development Kit (ADK) is a flexible and modular framework for developing and deploying AI agents. It's designed to make agent development feel more like software development, providing:
+
+### Key Benefits
+
+- **Code-First Development**: Define agents, tools, and workflows directly in Python
+- **Model Agnostic**: Works with various LLMs, optimized for Gemini
+- **Rich Tool Ecosystem**: Pre-built tools and easy custom tool creation
+- **Multi-Agent Support**: Build complex systems with multiple specialized agents
+- **Production Ready**: Deploy to Cloud Run, Vertex AI, or any container platform
+
+### When to Use ADK
+
+- Building conversational AI applications
+- Creating specialized AI assistants
+- Developing multi-agent workflows
+- Integrating AI with existing systems
+- Rapid prototyping of AI solutions
+
+---
+
+## Installation and Setup
+
+### Requirements
+
+- Python 3.9 or higher
+- Google Cloud account (for Gemini models)
+- Optional: Docker for containerized deployment
+
+### Installation
+
+```bash
+# Install the latest stable version
+pip install google-adk
+
+# Or install from source for latest features
+pip install git+https://github.com/google/adk-python.git@main
+```
+
+### Authentication Setup
+
+For Google Cloud services (recommended for production):
+
+```bash
+# Install Google Cloud CLI
+# https://cloud.google.com/sdk/docs/install
+
+# Authenticate
+gcloud auth application-default login
+
+# Set your project
+gcloud config set project YOUR_PROJECT_ID
+```
+
+Alternatively, use service account credentials:
+
+```python
+import os
+os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "path/to/your/credentials.json"
+```
+
+### Verify Installation
+
+```python
+from google.adk import Agent
+print("Google ADK installed successfully!")
+```
+
+---
+
+## Core Concepts
+
+### Agents
+
+Agents are the primary building blocks in ADK. They encapsulate:
+- **Model**: The LLM (e.g., Gemini) that powers the agent
+- **Instructions**: How the agent should behave
+- **Tools**: Capabilities the agent can use
+- **Context**: Information about the current conversation
+
+### Tools
+
+Tools extend agent capabilities by providing access to:
+- External APIs and services
+- Database operations
+- File system access
+- Custom business logic
+- Other agents
+
+### Sessions
+
+Sessions manage conversation state and history:
+- User and session identification
+- Message history
+- Context preservation
+- State management
+
+### Runners
+
+Runners orchestrate agent execution:
+- Message processing
+- Event generation
+- Service coordination
+- Error handling
+
+---
+
+## Your First Agent
+
+Let's build a simple assistant to understand the basics.
+
+### Step 1: Basic Agent
+
+```python
+from google.adk import Agent, Runner
+from google.adk.sessions import InMemorySessionService
+
+# Create a simple agent
+assistant = Agent(
+ name="my_first_agent",
+ model="gemini-2.0-flash",
+ instruction="You are a helpful assistant. Be friendly and concise."
+)
+
+# Set up session management
+session_service = InMemorySessionService()
+
+# Create a runner to execute the agent
+runner = Runner(
+ app_name="my_first_app",
+ agent=assistant,
+ session_service=session_service
+)
+
+# Test the agent
+for event in runner.run(
+ user_id="user123",
+ session_id="session456",
+ new_message="Hello! What can you help me with?"
+):
+ if event.type == "model_response":
+ print(f"Assistant: {event.data.get('text', '')}")
+```
+
+### Step 2: Understanding Events
+
+The runner generates events during execution:
+
+```python
+for event in runner.run(
+ user_id="user123",
+ session_id="session456",
+ new_message="Tell me a joke"
+):
+ print(f"Event Type: {event.type}")
+ print(f"Event Data: {event.data}")
+
+ # Common event types:
+ if event.type == "model_request":
+ print("Sending request to model...")
+ elif event.type == "model_response":
+ print(f"Model responded: {event.data.get('text', '')}")
+ elif event.type == "tool_call":
+ print(f"Tool called: {event.data.get('tool_name', '')}")
+```
+
+### Step 3: Adding Personality
+
+```python
+# Create an agent with more personality
+creative_agent = Agent(
+ name="creative_assistant",
+ model="gemini-2.0-flash",
+ instruction="""You are a creative writing assistant named Alex. You:
+ - Love helping people with creative projects
+ - Speak enthusiastically about storytelling
+ - Provide specific, actionable advice
+ - Always encourage creativity
+ - Use emojis occasionally to be friendly ✨"""
+)
+
+runner = Runner(
+ app_name="creative_app",
+ agent=creative_agent,
+ session_service=session_service
+)
+
+for event in runner.run(
+ user_id="writer",
+ session_id="writing_session",
+ new_message="I'm stuck on my story. The main character needs motivation."
+):
+ if event.type == "model_response":
+ print(f"Alex: {event.data.get('text', '')}")
+```
+
+---
+
+## Working with Tools
+
+Tools are what make agents truly powerful. Let's explore different types.
+
+### Built-in Tools
+
+#### Google Search
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import google_search
+from google.adk.sessions import InMemorySessionService
+
+# Create a research agent with Google Search
+research_agent = Agent(
+ name="researcher",
+ model="gemini-2.0-flash",
+ instruction="You are a research assistant. Use web search to find accurate, current information. Always cite your sources.",
+ tools=[google_search]
+)
+
+session_service = InMemorySessionService()
+runner = Runner(
+ app_name="research_app",
+ agent=research_agent,
+ session_service=session_service
+)
+
+# Test with a research question
+for event in runner.run(
+ user_id="student",
+ session_id="research_session",
+ new_message="What are the latest developments in renewable energy?"
+):
+ if event.type == "model_response":
+ print(f"Researcher: {event.data.get('text', '')}")
+```
+
+### Custom Function Tools
+
+Turn any Python function into a tool:
+
+```python
+from google.adk.tools import FunctionTool
+import random
+
+def roll_dice(sides: int = 6, count: int = 1) -> dict:
+ """Roll dice and return the results.
+
+ Args:
+ sides: Number of sides on each die (default: 6)
+ count: Number of dice to roll (default: 1)
+
+ Returns:
+ Dictionary with roll results
+ """
+ if sides < 2:
+ return {"error": "Dice must have at least 2 sides"}
+ if count < 1 or count > 10:
+ return {"error": "Can only roll 1-10 dice at once"}
+
+ rolls = [random.randint(1, sides) for _ in range(count)]
+ return {
+ "rolls": rolls,
+ "total": sum(rolls),
+ "sides": sides,
+ "count": count
+ }
+
+def calculate_tip(bill: float, percentage: float = 15.0) -> dict:
+ """Calculate tip and total bill amount.
+
+ Args:
+ bill: Original bill amount
+ percentage: Tip percentage (default: 15.0)
+
+ Returns:
+ Dictionary with tip calculations
+ """
+ if bill < 0:
+ return {"error": "Bill amount cannot be negative"}
+
+ tip = bill * (percentage / 100)
+ total = bill + tip
+
+ return {
+ "original_bill": round(bill, 2),
+ "tip_percentage": percentage,
+ "tip_amount": round(tip, 2),
+ "total_amount": round(total, 2)
+ }
+
+# Create tools from functions
+dice_tool = FunctionTool(func=roll_dice)
+tip_tool = FunctionTool(func=calculate_tip)
+
+# Create a utility agent
+utility_agent = Agent(
+ name="utility_bot",
+ model="gemini-2.0-flash",
+ instruction="You are a helpful utility bot. You can roll dice for games and calculate tips for restaurants. Be friendly and explain what you're doing.",
+ tools=[dice_tool, tip_tool]
+)
+
+# Test the utility agent
+runner = Runner(
+ app_name="utility_app",
+ agent=utility_agent,
+ session_service=InMemorySessionService()
+)
+
+for event in runner.run(
+ user_id="gamer",
+ session_id="game_session",
+ new_message="Roll 2 six-sided dice for my board game, then calculate a 20% tip on a $45 bill"
+):
+ if event.type == "model_response":
+ print(f"Utility Bot: {event.data.get('text', '')}")
+```
+
+### Custom Tool Classes
+
+For more complex logic, create custom tool classes:
+
+```python
+from google.adk.tools import BaseTool, ToolContext
+from typing import Any, Optional
+from google.genai import types
+import requests
+
+class WeatherTool(BaseTool):
+ """Custom tool for weather information."""
+
+ def __init__(self, api_key: str):
+ super().__init__(
+ name="weather_lookup",
+ description="Get current weather information for any city"
+ )
+ self.api_key = api_key
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ city = args.get("city")
+ if not city:
+ return {"error": "City name is required"}
+
+ # For demo purposes, return simulated data
+ # In production, you'd call a real weather API
+ weather_data = {
+ "city": city,
+ "temperature": "22°C (72°F)",
+ "condition": "Partly cloudy",
+ "humidity": "65%",
+ "wind": "8 km/h NW",
+ "feels_like": "24°C (75°F)"
+ }
+
+ return weather_data
+
+ def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
+ """Define the tool's parameters for the LLM."""
+ return types.FunctionDeclaration(
+ name=self.name,
+ description=self.description,
+ parameters=types.Schema(
+ type=types.Type.OBJECT,
+ properties={
+ "city": types.Schema(
+ type=types.Type.STRING,
+ description="The city name to get weather for"
+ )
+ },
+ required=["city"]
+ )
+ )
+
+# Use the custom tool
+weather_tool = WeatherTool(api_key="your_api_key_here")
+
+weather_agent = Agent(
+ name="weather_bot",
+ model="gemini-2.0-flash",
+ instruction="You are a weather assistant. Provide current weather information for any city requested. Be helpful and include relevant details.",
+ tools=[weather_tool]
+)
+
+runner = Runner(
+ app_name="weather_app",
+ agent=weather_agent,
+ session_service=InMemorySessionService()
+)
+
+for event in runner.run(
+ user_id="traveler",
+ session_id="weather_session",
+ new_message="What's the weather like in Tokyo right now?"
+):
+ if event.type == "model_response":
+ print(f"Weather Bot: {event.data.get('text', '')}")
+```
+
+---
+
+## Multi-Agent Systems
+
+ADK excels at building systems where multiple specialized agents work together.
+
+### Basic Multi-Agent Setup
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import google_search, AgentTool
+from google.adk.sessions import InMemorySessionService
+
+# Create specialized agents
+researcher = Agent(
+ name="researcher",
+ model="gemini-2.0-flash",
+ instruction="""You are a research specialist. Your job is to:
+ - Find accurate, up-to-date information using web search
+ - Organize findings clearly with bullet points
+ - Include relevant sources and statistics
+ - Focus on facts and data""",
+ tools=[google_search]
+)
+
+writer = Agent(
+ name="writer",
+ model="gemini-2.0-flash",
+ instruction="""You are a content writer. Your job is to:
+ - Take research data and create engaging articles
+ - Use clear, accessible language
+ - Structure content with headers and sections
+ - Make complex topics easy to understand"""
+)
+
+# Create tools from the specialized agents
+research_tool = AgentTool(agent=researcher)
+writing_tool = AgentTool(agent=writer)
+
+# Coordinator agent that uses the specialists
+coordinator = Agent(
+ name="content_coordinator",
+ model="gemini-2.0-flash",
+ instruction="""You coordinate content creation. Follow this process:
+
+ 1. First, use the research tool to gather information on the topic
+ 2. Then, use the writing tool to create engaging content from the research
+ 3. Present the final content to the user
+
+ Always follow this sequence and explain what you're doing at each step.""",
+ tools=[research_tool, writing_tool]
+)
+
+# Run the multi-agent system
+runner = Runner(
+ app_name="content_creation",
+ agent=coordinator,
+ session_service=InMemorySessionService()
+)
+
+for event in runner.run(
+ user_id="content_creator",
+ session_id="creation_session",
+ new_message="Create an article about electric vehicles and their environmental impact"
+):
+ if event.type == "model_response":
+ print(f"Coordinator: {event.data.get('text', '')}")
+```
+
+### Hierarchical Agent Structure
+
+```python
+# Create a hierarchical system with sub-agents
+greeter = Agent(
+ name="greeter",
+ model="gemini-2.0-flash",
+ instruction="You handle greetings and introductions. Be warm and welcoming. Ask users what they need help with."
+)
+
+support_agent = Agent(
+ name="support_specialist",
+ model="gemini-2.0-flash",
+ instruction="You handle customer support issues. Be helpful and solution-focused. Escalate complex issues when needed."
+)
+
+sales_agent = Agent(
+ name="sales_specialist",
+ model="gemini-2.0-flash",
+ instruction="You handle sales inquiries. Be informative about products and pricing. Help customers make decisions."
+)
+
+# Main agent with sub-agents
+main_agent = Agent(
+ name="customer_service",
+ model="gemini-2.0-flash",
+ instruction="""You are a customer service coordinator. You have access to specialized team members:
+ - Greeter: For welcoming new customers
+ - Support: For technical issues and problems
+ - Sales: For product information and purchases
+
+ Route customers to the appropriate specialist based on their needs.""",
+ sub_agents=[greeter, support_agent, sales_agent]
+)
+
+runner = Runner(
+ app_name="customer_service",
+ agent=main_agent,
+ session_service=InMemorySessionService()
+)
+
+# Test the hierarchical system
+test_messages = [
+ "Hi there! I'm new here.",
+ "I'm having trouble with my account login.",
+ "I want to know about your premium plans."
+]
+
+for i, message in enumerate(test_messages, 1):
+ print(f"\n=== Test {i}: {message} ===")
+ for event in runner.run(
+ user_id=f"customer_{i}",
+ session_id=f"session_{i}",
+ new_message=message
+ ):
+ if event.type == "model_response":
+ print(f"Response: {event.data.get('text', '')}")
+```
+
+---
+
+## Advanced Features
+
+### Memory and State Management
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import FunctionTool, load_memory, preload_memory
+from google.adk.sessions import InMemorySessionService
+from google.adk.memory import InMemoryMemoryService
+
+# Create a stateful agent that remembers user preferences
+def save_preference(key: str, value: str) -> dict:
+ """Save a user preference."""
+ # In production, save to database
+ print(f"Saving: {key} = {value}")
+ return {"saved": True, "key": key, "value": value}
+
+def get_preference(key: str) -> dict:
+ """Get a user preference."""
+ # Simulated preferences
+ prefs = {"theme": "dark", "language": "en"}
+ return {"key": key, "value": prefs.get(key, "not_set")}
+
+stateful_agent = Agent(
+ name="personal_assistant",
+ model="gemini-2.0-flash",
+ instruction="""You are a personal assistant that remembers user preferences.
+ You can save and retrieve preferences, and you maintain conversation context.
+ Always personalize responses based on saved preferences.""",
+ tools=[
+ FunctionTool(func=save_preference),
+ FunctionTool(func=get_preference),
+ load_memory,
+ preload_memory
+ ]
+)
+
+# Set up with memory service
+memory_service = InMemoryMemoryService()
+runner = Runner(
+ app_name="personal_app",
+ agent=stateful_agent,
+ session_service=InMemorySessionService(),
+ memory_service=memory_service
+)
+
+# Test conversation with memory
+print("=== Setting preferences ===")
+for event in runner.run(
+ user_id="john",
+ session_id="personal_session",
+ new_message="Hi! Please save my theme preference as 'dark' and language as 'english'"
+):
+ if event.type == "model_response":
+ print(f"Assistant: {event.data.get('text', '')}")
+
+print("\n=== Using saved preferences ===")
+for event in runner.run(
+ user_id="john",
+ session_id="personal_session",
+ new_message="What's my theme preference?"
+):
+ if event.type == "model_response":
+ print(f"Assistant: {event.data.get('text', '')}")
+```
+
+### Callbacks and Monitoring
+
+```python
+from google.adk import Agent, Runner
+from google.adk.tools import FunctionTool
+from google.adk.sessions import InMemorySessionService
+
+# Callback functions for monitoring
+async def before_model_callback(context, request):
+ """Called before each model request."""
+ print(f"🤖 Sending request to model: {request.model}")
+ return None
+
+async def after_model_callback(context, response):
+ """Called after each model response."""
+ print(f"✅ Model responded with {len(response.text)} characters")
+ return None
+
+async def before_tool_callback(tool, args, context):
+ """Called before each tool execution."""
+ print(f"🔧 Executing tool: {tool.name} with args: {args}")
+ return None
+
+async def after_tool_callback(tool, args, context, result):
+ """Called after each tool execution."""
+ print(f"✅ Tool {tool.name} completed successfully")
+ return None
+
+def simple_calculator(operation: str, a: float, b: float) -> dict:
+ """Perform basic math operations."""
+ if operation == "add":
+ return {"result": a + b}
+ elif operation == "subtract":
+ return {"result": a - b}
+ elif operation == "multiply":
+ return {"result": a * b}
+ elif operation == "divide":
+ return {"result": a / b if b != 0 else "Error: Division by zero"}
+ else:
+ return {"error": "Unknown operation"}
+
+# Create agent with callbacks
+monitored_agent = Agent(
+ name="calculator",
+ model="gemini-2.0-flash",
+ instruction="You are a calculator bot. Use the calculator tool for math operations.",
+ tools=[FunctionTool(func=simple_calculator)],
+ before_model_callbacks=before_model_callback,
+ after_model_callbacks=after_model_callback,
+ before_tool_callbacks=before_tool_callback,
+ after_tool_callbacks=after_tool_callback
+)
+
+runner = Runner(
+ app_name="monitored_app",
+ agent=monitored_agent,
+ session_service=InMemorySessionService()
+)
+
+for event in runner.run(
+ user_id="math_user",
+ session_id="calc_session",
+ new_message="Calculate 15 + 27 and then multiply the result by 3"
+):
+ if event.type == "model_response":
+ print(f"Calculator: {event.data.get('text', '')}")
+```
+
+---
+
+## Best Practices
+
+### 1. Agent Design
+
+**Keep Agents Focused**
+```python
+# Good: Specialized agent
+search_agent = Agent(
+ name="web_searcher",
+ model="gemini-2.0-flash",
+ instruction="You only search the web. Provide search results clearly and cite sources.",
+ tools=[google_search]
+)
+
+# Avoid: Jack-of-all-trades agents
+```
+
+**Clear Instructions**
+```python
+# Good: Specific, actionable instructions
+agent = Agent(
+ name="customer_support",
+ model="gemini-2.0-flash",
+ instruction="""You are a customer support agent. Follow these steps:
+ 1. Greet the customer warmly
+ 2. Listen to their issue carefully
+ 3. Search the knowledge base for solutions
+ 4. Provide clear, step-by-step help
+ 5. Ask for confirmation that the issue is resolved
+
+ Always be patient and professional."""
+)
+```
+
+### 2. Tool Development
+
+**Robust Error Handling**
+```python
+def safe_division(a: float, b: float) -> dict:
+ """Safely divide two numbers."""
+ try:
+ if b == 0:
+ return {"error": "Cannot divide by zero", "a": a, "b": b}
+ result = a / b
+ return {"result": result, "a": a, "b": b}
+ except Exception as e:
+ return {"error": f"Calculation error: {str(e)}", "a": a, "b": b}
+```
+
+**Input Validation**
+```python
+def validate_email(email: str) -> dict:
+ """Validate an email address."""
+ import re
+
+ if not email or not isinstance(email, str):
+ return {"valid": False, "error": "Email is required"}
+
+ pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
+ is_valid = re.match(pattern, email) is not None
+
+ return {
+ "valid": is_valid,
+ "email": email,
+ "message": "Valid email" if is_valid else "Invalid email format"
+ }
+```
+
+### 3. Performance Optimization
+
+**Use Async Operations**
+```python
+import asyncio
+import aiohttp
+
+class AsyncAPITool(BaseTool):
+ """Async tool for better performance."""
+
+ async def run_async(self, *, args: dict[str, Any], tool_context: ToolContext) -> Any:
+ async with aiohttp.ClientSession() as session:
+ async with session.get("https://api.example.com/data") as response:
+ return await response.json()
+```
+
+**Efficient Tool Selection**
+```python
+# Good: Specific tools for specific tasks
+math_agent = Agent(
+ name="mathematician",
+ model="gemini-2.0-flash",
+ instruction="You solve math problems using the calculator tool.",
+ tools=[calculator_tool] # Only what's needed
+)
+```
+
+### 4. Testing Strategies
+
+**Unit Test Your Tools**
+```python
+import pytest
+from your_tools import calculator_tool
+
+def test_calculator_addition():
+ result = calculator_tool.run_sync(
+ args={"operation": "add", "a": 5, "b": 3},
+ tool_context=mock_context
+ )
+ assert result["result"] == 8
+
+def test_calculator_division_by_zero():
+ result = calculator_tool.run_sync(
+ args={"operation": "divide", "a": 10, "b": 0},
+ tool_context=mock_context
+ )
+ assert "error" in result
+```
+
+**Integration Testing**
+```python
+def test_agent_with_tools():
+ """Test agent behavior with tools."""
+ agent = Agent(
+ name="test_agent",
+ model="gemini-2.0-flash",
+ instruction="You are a test agent.",
+ tools=[calculator_tool]
+ )
+
+ runner = Runner(
+ app_name="test_app",
+ agent=agent,
+ session_service=InMemorySessionService()
+ )
+
+ # Test the interaction
+ events = list(runner.run(
+ user_id="test",
+ session_id="test",
+ new_message="Calculate 5 + 3"
+ ))
+
+ # Verify expected behavior
+ assert any(event.type == "model_response" for event in events)
+```
+
+---
+
+## Troubleshooting
+
+### Common Issues
+
+**1. Import Errors**
+```python
+# Problem: ModuleNotFoundError
+# Solution: Check installation
+pip list | grep google-adk
+
+# Reinstall if needed
+pip install --upgrade google-adk
+```
+
+**2. Authentication Issues**
+```python
+# Problem: Authentication failed
+# Solution: Check credentials
+import os
+print(os.environ.get("GOOGLE_APPLICATION_CREDENTIALS"))
+
+# Or use gcloud auth
+# gcloud auth application-default login
+```
+
+**3. Tool Not Being Called**
+```python
+# Problem: Agent doesn't use tools
+# Common causes:
+# - Missing tool registration
+# - Unclear tool description
+# - Conflicting instructions
+
+# Solution: Clear tool descriptions
+tool = FunctionTool(func=my_function)
+print(tool.description) # Should be clear and specific
+```
+
+**4. Memory/Session Issues**
+```python
+# Problem: Agent doesn't remember context
+# Solution: Use proper session management
+session_service = InMemorySessionService() # For development
+# or DatabaseSessionService() # For production
+
+# Ensure same user_id and session_id for continuity
+```
+
+### Debugging Tips
+
+**Enable Logging**
+```python
+import logging
+logging.basicConfig(level=logging.DEBUG)
+
+# This will show detailed execution logs
+```
+
+**Event Monitoring**
+```python
+# Monitor all events for debugging
+for event in runner.run(...):
+ print(f"Event: {event.type} | Data: {event.data}")
+```
+
+**Tool Testing**
+```python
+# Test tools independently
+from google.adk.tools import ToolContext
+
+context = ToolContext(session_id="test", user_id="test")
+result = await my_tool.run_async(
+ args={"param": "value"},
+ tool_context=context
+)
+print(result)
+```
+
+---
+
+## Next Steps
+
+Now that you understand the basics of Google ADK:
+
+1. **Explore the [API Reference](api-reference.md)** for detailed documentation
+2. **Check out [Examples](examples.md)** for more complex use cases
+3. **Read the [Tools Guide](tools-guide.md)** for advanced tool development
+4. **Join the community** for support and discussions
+
+### Additional Resources
+
+- [Google ADK Documentation](https://google.github.io/adk-docs)
+- [Sample Projects](https://github.com/google/adk-samples)
+- [ADK Web Interface](https://github.com/google/adk-web)
+- [Community Forum](https://www.reddit.com/r/agentdevelopmentkit/)
+
+Happy agent building! 🚀
\ No newline at end of file
diff --git a/docs/utilities-guide.md b/docs/utilities-guide.md
new file mode 100644
index 00000000000..dbe35454ea3
--- /dev/null
+++ b/docs/utilities-guide.md
@@ -0,0 +1,566 @@
+# Google ADK Utilities Guide
+
+This guide documents the utility functions and helper classes available in the Google Agent Development Kit (ADK).
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Model Utilities](#model-utilities)
+- [Feature Decorators](#feature-decorators)
+- [Instruction Utilities](#instruction-utilities)
+- [Variant Utilities](#variant-utilities)
+- [Usage Examples](#usage-examples)
+
+---
+
+## Overview
+
+ADK provides several utility modules to help with common tasks in agent development:
+
+- **Model Name Utilities**: Functions for parsing and validating model names
+- **Feature Decorators**: Decorators for marking experimental features
+- **Instruction Utilities**: Functions for processing agent instructions and session state
+- **Variant Utilities**: Utilities for working with different Google LLM variants
+
+---
+
+## Model Utilities
+
+**Module**: `google.adk.utils.model_name_utils`
+
+Utilities for model name validation and parsing.
+
+### `extract_model_name(model_string: str) -> str`
+
+Extract the actual model name from either simple or path-based format.
+
+```python
+from google.adk.utils.model_name_utils import extract_model_name
+
+# Simple model name
+model_name = extract_model_name("gemini-2.0-flash")
+print(model_name) # Output: "gemini-2.0-flash"
+
+# Path-based model name
+path_model = "projects/my-project/locations/us-central1/publishers/google/models/gemini-2.0-flash-001"
+model_name = extract_model_name(path_model)
+print(model_name) # Output: "gemini-2.0-flash-001"
+```
+
+**Parameters:**
+- `model_string`: Either a simple model name like "gemini-2.0-flash" or a path-based model name
+
+**Returns:**
+- The extracted model name
+
+### `is_gemini_model(model_string: Optional[str]) -> bool`
+
+Check if the model is a Gemini model.
+
+```python
+from google.adk.utils.model_name_utils import is_gemini_model
+
+# Test various model names
+print(is_gemini_model("gemini-2.0-flash")) # True
+print(is_gemini_model("gemini-1.5-pro")) # True
+print(is_gemini_model("gpt-4")) # False
+print(is_gemini_model(None)) # False
+```
+
+**Parameters:**
+- `model_string`: Model name to check (can be None)
+
+**Returns:**
+- `True` if it's a Gemini model, `False` otherwise
+
+### `is_gemini_1_model(model_string: Optional[str]) -> bool`
+
+Check if the model is a Gemini 1.x model.
+
+```python
+from google.adk.utils.model_name_utils import is_gemini_1_model
+
+print(is_gemini_1_model("gemini-1.5-pro")) # True
+print(is_gemini_1_model("gemini-1.0-pro")) # True
+print(is_gemini_1_model("gemini-2.0-flash")) # False
+```
+
+**Parameters:**
+- `model_string`: Model name to check
+
+**Returns:**
+- `True` if it's a Gemini 1.x model, `False` otherwise
+
+### `is_gemini_2_model(model_string: Optional[str]) -> bool`
+
+Check if the model is a Gemini 2.x model.
+
+```python
+from google.adk.utils.model_name_utils import is_gemini_2_model
+
+print(is_gemini_2_model("gemini-2.0-flash")) # True
+print(is_gemini_2_model("gemini-2.5-pro")) # True
+print(is_gemini_2_model("gemini-1.5-pro")) # False
+```
+
+**Parameters:**
+- `model_string`: Model name to check
+
+**Returns:**
+- `True` if it's a Gemini 2.x model, `False` otherwise
+
+### Complete Model Utilities Example
+
+```python
+from google.adk.utils.model_name_utils import (
+ extract_model_name,
+ is_gemini_model,
+ is_gemini_1_model,
+ is_gemini_2_model
+)
+
+def analyze_model(model_string: str):
+ """Analyze a model string and provide information about it."""
+ model_name = extract_model_name(model_string)
+
+ print(f"Original: {model_string}")
+ print(f"Extracted: {model_name}")
+ print(f"Is Gemini: {is_gemini_model(model_string)}")
+ print(f"Is Gemini 1.x: {is_gemini_1_model(model_string)}")
+ print(f"Is Gemini 2.x: {is_gemini_2_model(model_string)}")
+ print("---")
+
+# Test with different model formats
+models = [
+ "gemini-2.0-flash",
+ "gemini-1.5-pro",
+ "projects/my-project/locations/us/publishers/google/models/gemini-2.0-flash-001",
+ "gpt-4",
+ "claude-3"
+]
+
+for model in models:
+ analyze_model(model)
+```
+
+---
+
+## Feature Decorators
+
+**Module**: `google.adk.utils.feature_decorator`
+
+Decorators for marking features as experimental or work-in-progress.
+
+### `@experimental`
+
+Mark classes, functions, or methods as experimental.
+
+```python
+from google.adk.utils.feature_decorator import experimental
+
+@experimental
+class ExperimentalFeature:
+ """This is an experimental feature that may change in future versions."""
+
+ def __init__(self):
+ self.name = "experimental"
+
+ @experimental
+ def experimental_method(self):
+ """This method is experimental."""
+ return "experimental result"
+
+@experimental
+def experimental_function():
+ """This function is experimental and may be removed or changed."""
+ return "experimental output"
+
+# Usage
+feature = ExperimentalFeature()
+result = feature.experimental_method()
+output = experimental_function()
+```
+
+**Purpose:**
+- Warn users that the feature is experimental
+- Indicate that the API may change in future versions
+- Help track which features are stable vs. experimental
+
+### `@working_in_progress`
+
+Mark features as work-in-progress (WIP).
+
+```python
+from google.adk.utils.feature_decorator import working_in_progress
+
+@working_in_progress
+class WIPFeature:
+ """This feature is still being developed."""
+ pass
+
+@working_in_progress
+def wip_function():
+ """This function is work-in-progress."""
+ pass
+```
+
+### Custom Feature Decorators
+
+You can also create custom feature decorators:
+
+```python
+from google.adk.utils.feature_decorator import _make_feature_decorator
+
+# Create a custom decorator for beta features
+beta = _make_feature_decorator(
+ flag_name="beta",
+ warning_message="This feature is in beta and may have limitations."
+)
+
+@beta
+class BetaFeature:
+ """This is a beta feature."""
+ pass
+```
+
+---
+
+## Instruction Utilities
+
+**Module**: `google.adk.utils.instructions_utils`
+
+Utilities for processing agent instructions and session state injection.
+
+### `inject_session_state(instruction: str, session_state: dict) -> str`
+
+Inject session state variables into instruction templates.
+
+```python
+from google.adk.utils.instructions_utils import inject_session_state
+
+# Template with placeholders
+instruction_template = """
+You are a helpful assistant named {{agent_name}}.
+The current user is {{user_name}} and their preferred language is {{language}}.
+Today's date is {{current_date}}.
+"""
+
+# Session state data
+session_state = {
+ "agent_name": "Alex",
+ "user_name": "John",
+ "language": "English",
+ "current_date": "2024-01-15"
+}
+
+# Inject state into instruction
+final_instruction = inject_session_state(instruction_template, session_state)
+print(final_instruction)
+# Output:
+# You are a helpful assistant named Alex.
+# The current user is John and their preferred language is English.
+# Today's date is 2024-01-15.
+```
+
+**Parameters:**
+- `instruction`: Instruction template with `{{variable}}` placeholders
+- `session_state`: Dictionary of state variables
+
+**Returns:**
+- Instruction with placeholders replaced by state values
+
+### Advanced Instruction Processing
+
+```python
+from google.adk.utils.instructions_utils import inject_session_state
+
+# Complex instruction template
+instruction = """
+Hello {{user_name}}! I'm {{assistant_name}}, your {{assistant_type}} assistant.
+
+Current Context:
+- Session ID: {{session_id}}
+- User Preferences: {{preferences}}
+- Current Task: {{current_task}}
+
+{{#if has_history}}
+I remember our previous conversations.
+{{/if}}
+
+How can I help you today?
+"""
+
+# Rich session state
+session_state = {
+ "user_name": "Sarah",
+ "assistant_name": "Ada",
+ "assistant_type": "AI coding",
+ "session_id": "sess_12345",
+ "preferences": "Dark theme, Python focus",
+ "current_task": "Code review",
+ "has_history": True
+}
+
+personalized_instruction = inject_session_state(instruction, session_state)
+```
+
+---
+
+## Variant Utilities
+
+**Module**: `google.adk.utils.variant_utils`
+
+Utilities for working with different Google LLM variants.
+
+### `GoogleLLMVariant`
+
+Enum for Google LLM variants.
+
+```python
+from google.adk.utils.variant_utils import GoogleLLMVariant
+
+# Available variants
+print(GoogleLLMVariant.VERTEX_AI.value) # "VERTEX_AI"
+print(GoogleLLMVariant.GEMINI_API.value) # "GEMINI_API"
+```
+
+**Variants:**
+- `VERTEX_AI`: For using credentials from Google Vertex AI
+- `GEMINI_API`: For using API Key from Google AI Studio
+
+### `get_google_llm_variant() -> str`
+
+Get the current Google LLM variant based on environment variables.
+
+```python
+import os
+from google.adk.utils.variant_utils import get_google_llm_variant, GoogleLLMVariant
+
+# Default behavior (returns GEMINI_API)
+variant = get_google_llm_variant()
+print(variant) # GoogleLLMVariant.GEMINI_API
+
+# Set environment variable to use Vertex AI
+os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "true"
+variant = get_google_llm_variant()
+print(variant) # GoogleLLMVariant.VERTEX_AI
+
+# Alternative ways to enable Vertex AI
+os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "1"
+variant = get_google_llm_variant()
+print(variant) # GoogleLLMVariant.VERTEX_AI
+```
+
+**Environment Variable:**
+- `GOOGLE_GENAI_USE_VERTEXAI`: Set to "true" or "1" to use Vertex AI variant
+
+**Returns:**
+- `GoogleLLMVariant.VERTEX_AI` if environment variable is set
+- `GoogleLLMVariant.GEMINI_API` otherwise (default)
+
+---
+
+## Usage Examples
+
+### Model-Aware Agent Creation
+
+```python
+from google.adk import Agent
+from google.adk.utils.model_name_utils import is_gemini_2_model
+from google.adk.tools import google_search
+
+def create_smart_agent(model_name: str) -> Agent:
+ """Create an agent with model-specific optimizations."""
+
+ # Base configuration
+ agent_config = {
+ "name": "smart_agent",
+ "model": model_name,
+ "instruction": "You are a helpful assistant."
+ }
+
+ # Add Google Search for Gemini 2.x models
+ if is_gemini_2_model(model_name):
+ agent_config["tools"] = [google_search]
+ agent_config["instruction"] += " You can search the web for current information."
+
+ return Agent(**agent_config)
+
+# Usage
+agent1 = create_smart_agent("gemini-2.0-flash") # Will have search capability
+agent2 = create_smart_agent("gemini-1.5-pro") # Will not have search
+```
+
+### Environment-Aware Configuration
+
+```python
+import os
+from google.adk.utils.variant_utils import get_google_llm_variant, GoogleLLMVariant
+
+def configure_model_for_environment():
+ """Configure model settings based on environment."""
+
+ variant = get_google_llm_variant()
+
+ if variant == GoogleLLMVariant.VERTEX_AI:
+ print("Using Vertex AI configuration")
+ # Configure for Vertex AI
+ model_config = {
+ "project_id": os.environ.get("GOOGLE_CLOUD_PROJECT"),
+ "location": "us-central1"
+ }
+ else:
+ print("Using Gemini API configuration")
+ # Configure for Gemini API
+ model_config = {
+ "api_key": os.environ.get("GOOGLE_API_KEY")
+ }
+
+ return model_config
+
+# Usage
+config = configure_model_for_environment()
+```
+
+### Dynamic Instruction Generation
+
+```python
+from google.adk import Agent
+from google.adk.utils.instructions_utils import inject_session_state
+import datetime
+
+def create_personalized_agent(user_profile: dict) -> Agent:
+ """Create an agent with personalized instructions."""
+
+ instruction_template = """
+You are {{assistant_name}}, a personalized AI assistant.
+
+User Profile:
+- Name: {{user_name}}
+- Preferred Language: {{language}}
+- Experience Level: {{experience_level}}
+- Interests: {{interests}}
+
+Current Context:
+- Date: {{current_date}}
+- Time: {{current_time}}
+
+Adapt your responses to the user's experience level and interests.
+Be {{communication_style}} in your communication.
+"""
+
+ # Prepare session state
+ now = datetime.datetime.now()
+ session_state = {
+ "assistant_name": "Alex",
+ "current_date": now.strftime("%Y-%m-%d"),
+ "current_time": now.strftime("%H:%M"),
+ **user_profile # Merge user profile data
+ }
+
+ # Generate personalized instruction
+ personalized_instruction = inject_session_state(instruction_template, session_state)
+
+ return Agent(
+ name="personalized_assistant",
+ model="gemini-2.0-flash",
+ instruction=personalized_instruction
+ )
+
+# Usage
+user_profile = {
+ "user_name": "Alice",
+ "language": "English",
+ "experience_level": "beginner",
+ "interests": "programming, AI, books",
+ "communication_style": "friendly and encouraging"
+}
+
+agent = create_personalized_agent(user_profile)
+```
+
+### Experimental Feature Usage
+
+```python
+from google.adk.utils.feature_decorator import experimental
+from google.adk import Agent
+
+@experimental
+class AdvancedReasoningAgent(Agent):
+ """An experimental agent with advanced reasoning capabilities."""
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.reasoning_mode = "experimental"
+
+ @experimental
+ def advanced_reasoning(self, problem: str) -> str:
+ """Experimental advanced reasoning method."""
+ # This would contain experimental reasoning logic
+ return f"Advanced reasoning applied to: {problem}"
+
+# Usage with awareness of experimental nature
+agent = AdvancedReasoningAgent(
+ name="experimental_reasoner",
+ model="gemini-2.0-flash",
+ instruction="You are an experimental reasoning agent."
+)
+
+# The decorators will warn about experimental features
+result = agent.advanced_reasoning("Complex problem")
+```
+
+### Utility Function Composition
+
+```python
+from google.adk.utils.model_name_utils import extract_model_name, is_gemini_model
+from google.adk.utils.variant_utils import get_google_llm_variant
+from google.adk.utils.instructions_utils import inject_session_state
+
+def smart_agent_factory(model_string: str, user_context: dict) -> dict:
+ """Factory function that uses multiple utilities to create optimal agent config."""
+
+ # Extract and validate model
+ model_name = extract_model_name(model_string)
+ is_gemini = is_gemini_model(model_string)
+
+ # Get variant configuration
+ variant = get_google_llm_variant()
+
+ # Prepare instruction with context
+ instruction_template = """
+You are an AI assistant running on {{model_name}}.
+Variant: {{variant}}
+User: {{user_name}}
+Capabilities: {{capabilities}}
+"""
+
+ session_state = {
+ "model_name": model_name,
+ "variant": variant,
+ "user_name": user_context.get("name", "User"),
+ "capabilities": "Standard AI assistant" + (" with Gemini features" if is_gemini else "")
+ }
+
+ instruction = inject_session_state(instruction_template, session_state)
+
+ return {
+ "name": f"smart_agent_{model_name.replace('-', '_')}",
+ "model": model_string,
+ "instruction": instruction,
+ "metadata": {
+ "variant": variant,
+ "is_gemini": is_gemini,
+ "extracted_model": model_name
+ }
+ }
+
+# Usage
+user_context = {"name": "John", "preferences": "detailed explanations"}
+config = smart_agent_factory("gemini-2.0-flash", user_context)
+print(config)
+```
+
+---
+
+This utilities guide provides comprehensive documentation for all the helper functions and utilities available in Google ADK. These utilities help with common tasks like model validation, feature management, instruction processing, and environment configuration.
\ No newline at end of file
diff --git a/krnl_automation.py b/krnl_automation.py
new file mode 100644
index 00000000000..c0b94fdfdd4
--- /dev/null
+++ b/krnl_automation.py
@@ -0,0 +1,104 @@
+import re
+import time
+import subprocess
+import pyautogui
+import pyperclip
+from selenium import webdriver
+from selenium.webdriver.chrome.service import Service
+from webdriver_manager.chrome import ChromeDriverManager
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.support import expected_conditions as EC
+
+# Linux用のKRNLパス(実際のパスに変更してください)
+KRNL_PATH = "/path/to/krnl" # ここに実際のKRNL実行ファイルパスを入れてください
+
+def check_krnl_key(key: str):
+ pattern = re.compile(r'^[0-9a-fA-F]{4}(-[0-9a-fA-F]{4}){3}$')
+ return bool(pattern.match(key))
+
+def auto_get_key_full():
+ print("\n[+] KRNLキー取得自動化を開始します...")
+ driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
+ driver.get("https://krnl.gg/getkey")
+
+ wait = WebDriverWait(driver, 60)
+ krnl_key = None
+
+ try:
+ next_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '次へ')]")))
+ time.sleep(1)
+ next_btn.click()
+ print("[+] '次へ'ボタンをクリックしました")
+
+ time.sleep(5)
+ continue_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '続行')]")))
+ continue_btn.click()
+ print("[+] '続行'ボタンをクリックしました")
+
+ key_element = wait.until(EC.presence_of_element_located((By.XPATH, "//code")))
+ krnl_key = key_element.text.strip()
+ pyperclip.copy(krnl_key)
+ print(f"[+] 取得したキー: {krnl_key} (クリップボードにコピーしました)")
+
+ except Exception as e:
+ print("[-] 自動化中にエラー:", e)
+ finally:
+ driver.quit()
+
+ return krnl_key
+
+def focus_krnl_window():
+ """Linux用のウィンドウフォーカス関数"""
+ try:
+ # xdotoolを使用してKRNLウィンドウをアクティブにする
+ subprocess.run(["xdotool", "search", "--name", "KRNL", "windowactivate"], check=True)
+ time.sleep(1)
+ print("[+] KRNLウィンドウをアクティブにしました")
+ return True
+ except (subprocess.CalledProcessError, FileNotFoundError):
+ print("[-] xdotoolが見つからないか、KRNLウィンドウが見つかりません。")
+ print("[-] 手動でKRNLウィンドウをアクティブにしてください。")
+ time.sleep(5) # ユーザーに手動でアクティブにしてもらう時間
+ return True
+
+def inject_krnl(key):
+ print("\n[+] KRNLにキーを入力してInjectします...")
+ if not focus_krnl_window():
+ return
+
+ # キー入力欄クリック(位置は環境に合わせて調整)
+ pyautogui.click(500, 400)
+ time.sleep(0.5)
+
+ # キー貼り付け
+ pyautogui.hotkey("ctrl", "v")
+ time.sleep(0.5)
+
+ # Injectボタンクリック(位置は調整が必要)
+ pyautogui.click(600, 500)
+ time.sleep(1)
+
+ print("[+] Inject処理完了しました。")
+
+if __name__ == "__main__":
+ print("[+] KRNLを起動します...")
+ try:
+ subprocess.Popen([KRNL_PATH])
+ time.sleep(10) # 起動待機(PC環境によって調整してください)
+ except FileNotFoundError:
+ print("[-] KRNL実行ファイルが見つかりません。")
+ print("[-] KRNL_PATHを正しいパスに設定してください。")
+ print("[-] 手動でKRNLを起動してください。")
+ time.sleep(5)
+
+ user_key = input("既にKRNLキーを持っていますか?(なければEnter): ").strip()
+
+ if user_key and check_krnl_key(user_key):
+ print("\nこのキーは形式上OKです。Injectを開始します。")
+ inject_krnl(user_key)
+ else:
+ print("\nキーが無効 or 入力なしのため、自動取得します。")
+ key = auto_get_key_full()
+ if key:
+ inject_krnl(key)
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 00000000000..c2f40d36816
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+selenium>=4.0.0
+webdriver-manager>=3.8.0
+pyautogui>=0.9.54
+pyperclip>=1.8.2
\ No newline at end of file