Compare commits

..

192 Commits

Author SHA1 Message Date
Sasha Sobran e172811bc7 fix: unbreak client closed errors when using vertexai session service
PiperOrigin-RevId: 811911528
2025-09-26 12:16:37 -07:00
Xuan Yang da6f1d3653 chore: Release ADK 1.15.0
PiperOrigin-RevId: 811655912
2025-09-25 22:17:23 -07:00
Shangjie Chen 2c752934a8 feat: Skip running a workflow agent if it has no sub-agents
PiperOrigin-RevId: 811528166
2025-09-25 15:39:38 -07:00
Xinran (Sherry) Tang b2b80e7fa0 feat: Pause invocations on long running function calls for resumable apps
PiperOrigin-RevId: 811518771
2025-09-25 15:11:11 -07:00
Xuan Yang dd1ffad394 chore: Update google-genai version constraint
Fixes https://github.com/google/adk-python/issues/2968

PiperOrigin-RevId: 811475972
2025-09-25 13:21:45 -07:00
Shangjie Chen 8b081751ed feat: Add core checkpointing primitive for base agent
PiperOrigin-RevId: 811458903
2025-09-25 12:35:36 -07:00
Xinran (Sherry) Tang b5a65fb4f4 chore: Remove the too-detailed edge case descriptions for resumability
PiperOrigin-RevId: 811432962
2025-09-25 11:32:38 -07:00
Shangjie Chen 839d2e43bb feat: Define an AgentState to be used for resuming agent invocation
PiperOrigin-RevId: 811414736
2025-09-25 10:49:49 -07:00
Xiang (Sean) Zhou 1589fcdd86 chore: Replace github HTTP URIs with GCS HTTP URIs in static non-text content sample agent
mainly because http://github.com/robots.txt disallows `/*/raw/` path. using GCS HTTP URIs is more reliable with Gemini model.

PiperOrigin-RevId: 811409688
2025-09-25 10:38:04 -07:00
Max Ind e7528aebd4 feat(otel): adjust telemetry to follow OTLP 1.37 GenAI semconv
Changes include:
- Implementing missing attributes. e.g. 'gen_ai.agent.name'
- Specifying reasons for not filling out some conditionally required attributes. e.g. 'gen_ai.data_source.id'
- Specifying reasons for not including certain attributes which are specified in current semconv. e.g. inference attributes on agent spans

PiperOrigin-RevId: 811379706
2025-09-25 09:25:15 -07:00
Xinran (Sherry) Tang cbb6e4945a feat: Add a app level config for resumable applications
PiperOrigin-RevId: 811272046
2025-09-25 03:14:34 -07:00
Xiang (Sean) Zhou c6b6b6f3c6 chore: Add log-level parameter to cache analysis experiments
this is to allow turning on debug log for debugging if some unexpected behavior observed during running cache analysis experiments.

PiperOrigin-RevId: 811189954
2025-09-24 22:44:41 -07:00
Google Team Member c8c6cd70a4 feat: Introduce ExtendedOAuth2 scheme that auto-populates auth/token URLs
Use auto-discovered auth_endpoint and token_endpoint in CredentialManager.

PiperOrigin-RevId: 811183929
2025-09-24 22:21:07 -07:00
Xiang (Sean) Zhou f159bd9c87 fix: Use str() to calculate fingerprint instead of json.dumps
This is to avoid serialization issue for some fields that are not json serializable.
meanwhile restructure the debug logs in context cache manager for better debugging potential issues.

PiperOrigin-RevId: 811182492
2025-09-24 22:14:40 -07:00
Ankur Sharma d48679582d feat: Populate AppDetails to each Invocation
AppDetails require two pieces of information:
1) Instructions
2) Tools

Both these pieces of information are gathered using the llm_request that was passed to the model. This approach, slightly invasive, ensures that we capture the "exact" instructions and tools that were given to the model.

PiperOrigin-RevId: 811180648
2025-09-24 22:06:56 -07:00
Google Team Member 2a2da0fe03 feat: Introduce OAuth2DiscoveryManager to fetch metadata needed for OAuth
This is the first step to bring ADK to compliance with MCP Authorization Spec.

PiperOrigin-RevId: 811177152
2025-09-24 21:53:48 -07:00
Ankur Sharma 5a485b01cd feat: Adds Rubric based final response evaluator
The evaluator uses a set of rubrics to assess the quality of the agent's final response.

PiperOrigin-RevId: 811154498
2025-09-24 20:30:51 -07:00
Ankur Sharma 01923a9227 feat: Data model for storing App Details and data model for steps
Details:
1. Data model for storing App Details (the agentic system)
As we move towards LLM as Judge metrics, we see that some of these metrics need information about the Agentic system that was used for inferencing. We add a data model to capture that.

2. Data model for Steps
We refine the concept of intermediate data. Previously it stored data in the form of a multiple lists, thereby losing out on the chronological information. This information is needed for some of the metrics. So we refine the concept of intermediate data as series of logical steps that an Agent Take.

PiperOrigin-RevId: 811122784
2025-09-24 18:41:38 -07:00
Xiang (Sean) Zhou 08f3b48305 chore: Add sample agent to test non-text content in static instruction
PiperOrigin-RevId: 810999310
2025-09-24 13:03:11 -07:00
Xuan Yang 6db096a3f4 chore: remove unsupported 'type': 'unknown' in test_common.py for fastapi 0.117.1
PiperOrigin-RevId: 810673476
2025-09-23 19:44:49 -07:00
Xiang (Sean) Zhou 47bd34ac28 chore: Fix the type annotation
PiperOrigin-RevId: 810611299
2025-09-23 15:50:19 -07:00
Xiang (Sean) Zhou ae5592e242 chore: Add tests for instruction provider and merge test_static_instructions.py to test_intructions.py
PiperOrigin-RevId: 810610507
2025-09-23 15:47:46 -07:00
Xiang (Sean) Zhou 61213ce4d4 feat: Support non-text content in static instruction
move them to user contents and reference them from instruction

PiperOrigin-RevId: 810587466
2025-09-23 15:36:15 -07:00
Xuan Yang e86ca5762a chore: remove internal TODO comment
PiperOrigin-RevId: 810583734
2025-09-23 15:36:06 -07:00
Google Team Member cbb609233b chore: Sample Spanner RAG agent that wraps search_tool
Also modified README to add instructions on when to use which tool.

PiperOrigin-RevId: 810563458
2025-09-23 15:35:57 -07:00
George Weale 657369cffe fix: Adds plugin to save artifacts for issue #2176
PiperOrigin-RevId: 810522939
2025-09-23 15:35:48 -07:00
Xiang (Sean) Zhou c944a12e31 chore: Remove query schema mode, as it doesn't perform well as embedded schema mode
PiperOrigin-RevId: 810517055
2025-09-23 15:35:40 -07:00
Xiang (Sean) Zhou 26990c2622 chore: Add sample agent to test static instruction
PiperOrigin-RevId: 810516925
2025-09-23 15:35:31 -07:00
Xiang (Sean) Zhou f2ce990867 chore: Add experimental annotation to GeminiContextCacheManager
PiperOrigin-RevId: 810503537
2025-09-23 15:35:22 -07:00
shsha4 86dea5b53a fix(mcp): Initialize tool_name_prefix in MCPToolse
Merge https://github.com/google/adk-python/pull/2823

Description
  This change introduces a tool_name_prefix attribute to McpToolset and McpToolsetConfig. This allows for adding a prefix to the
  names of all tools within the toolset, which can help avoid naming collisions and provide better organization.

  The implementation involves updating the McpToolset's __init__ and from_config methods to handle the new tool_name_prefix and
  adding the corresponding field to McpToolsetConfig.

  Testing Plan
  A new unit test file has been added to ensure the functionality works as expected.

   - `tests/unittests/tools/test_mcp_toolset.py`:
     - The test_mcp_toolset_with_prefix test case verifies that the tool_name_prefix is correctly applied to the tool names
       retrieved from the toolset.
     - All tests were run via pytest and passed.

  Related Issue
   - Closes #2814

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2823 from shsha4:fix/issue-2814 e8e5b0d6d5f406d3875faf2229a96701725b7a5e
PiperOrigin-RevId: 810500616
2025-09-23 15:35:12 -07:00
Xiang (Sean) Zhou 6ca2aee829 ADK changes
PiperOrigin-RevId: 810492858
2025-09-23 15:35:02 -07:00
Xuan Yang 374522197f ADK changes
PiperOrigin-RevId: 810223422
2025-09-23 15:34:53 -07:00
Google Team Member aef1ee97a5 fix: make a copy of the columns instead of modifying it in place
This avoid unintentional modifications, especially in the case of a wrapped tool.

PiperOrigin-RevId: 810175539
2025-09-23 15:34:43 -07:00
Xiang (Sean) Zhou 38bbde6d56 chore: Annotate CachePerformanceAnalyzer as experimental
PiperOrigin-RevId: 809434619
2025-09-23 15:34:34 -07:00
TanejaAnkisetty 78fd4803d5 chore: Set role to user if new_message doesn't have role in Runner.run_async()
Merge https://github.com/google/adk-python/pull/2458

**Summary**
Verifies that user-provided messages are always passed to the LLM as 'user' role, regardless of whether the role is explicitly set in types.Content. Before the current fix, if the LlmRequest from the user doesn't have the 'user' role, but has the user content, then the text is being replaced with the standard text - "Handle the requests as specified in the System Instruction." and the content from the user is completely ignored and not passed into the LLM.

**Code to replicate the problem**

```
from google.adk.agents import LlmAgent
from google.adk.sessions import InMemorySessionService
from google.adk.runners import Runner
from google.genai.types import Content, Part
from google.adk.models.lite_llm import LiteLlm
from google.adk.models import LlmRequest
from google.genai import types
from pydantic import Field

import litellm
litellm._turn_on_debug()

import warnings
warnings.filterwarnings("ignore", category=UserWarning, message=".*InMemoryCredentialService.*")

import os
from dotenv import load_dotenv

# Load environment variables from the agent directory's .env file
load_dotenv()

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

# Define agent with output_key
root_agent = LlmAgent(
    name="name_of_agent",
    model=LiteLlm(model="azure/gpt-4o-mini"),
    instruction="You are a customer agent to help the users with their concerns."
)

# --- Setup Runner and Session ---
app_name, user_id, session_id = "state_app", "user1", "session1"

session_service = InMemorySessionService()

runner = Runner(
    agent=root_agent,
    app_name=app_name,
    session_service=session_service
)

print(f"Runner created for agent '{runner.agent.name}'.")

session = await session_service.create_session(
    app_name=app_name,
    user_id=user_id,
    session_id=session_id
)

# --- Run the Agent ---

async def call_agent_async(query: str, runner, user_id, session_id):

    user_message = Content(parts=[Part(text=query)])

    async for event in runner.run_async(
        user_id=user_id,
        session_id=session_id,
        new_message=user_message
    ):
        print("event")
        print(f"  [Event]\n  Author: {event.author}\n  Type: {type(event).__name__}",
        f"\n  Final: {event.is_final_response()}\n  Content: {event.content}")

    return event

event = await call_agent_async("What is the capital of India.",runner=runner,user_id=user_id,session_id=session_id)
```
**Before the fix (current adk-python code output)**
```
00:29:24 - LiteLLM:DEBUG: utils.py:348 -

00:29:24 - LiteLLM:DEBUG: utils.py:348 - Request to litellm:
00:29:24 - LiteLLM:DEBUG: utils.py:348 - litellm.acompletion(model='azure/gpt-4o-mini', messages=[{'role': 'developer', 'content': 'You are a customer agent to help the users with their concerns.\n\nYou are an agent. Your internal name is "name_of_agent".'}, {'role': 'user', 'content': 'Handle the requests as specified in the System Instruction.'}], tools=None, response_format=None)
```

**After the fix (after resolving the fix)**
```
00:28:46 - LiteLLM:DEBUG: utils.py:349 -

00:28:46 - LiteLLM:DEBUG: utils.py:349 - Request to litellm:
00:28:46 - LiteLLM:DEBUG: utils.py:349 - litellm.acompletion(model='azure/gpt-4o-mini', messages=[{'role': 'developer', 'content': 'You are a customer agent to help the users with their concerns.\n\nYou are an agent. Your internal name is "name_of_agent".'}, {'role': 'user', 'content': 'What is the capital of India.'}], tools=None, response_format=None)
```

**Testing**
Following unit test is created to test the applied changes and added in the location as suggested in the guidelines.
adk-python\tests\unittests\models\test_base_llm.py

```
import pytest
from google.genai import types
from google.adk.models.llm_request import LlmRequest
from google.adk.models.lite_llm import _get_completion_inputs

@pytest.mark.parametrize("content_kwargs", [
    # Case 1: Explicit role provided
    {"role": "user", "parts": [types.Part(text="This is an input text from user.")]},
    # Case 2: Role omitted, should still be treated as 'user'
    {"parts": [types.Part(text="This is an input text from user.")]}
])
def test_user_content_role_defaults_to_user(content_kwargs):
    """
    Verifies that user-provided messages are always passed to the LLM as 'user' role,
    regardless of whether the role is explicitly set in types.Content.

    The helper `_get_completion_inputs` should give normalize messages so that
    explicit 'user' and implicit (missing role) are equivalent.
    """
    llm_request = LlmRequest(
        contents=[types.Content(**content_kwargs)],
        config=types.GenerateContentConfig()
    )

    messages, _, _, _ = _get_completion_inputs(llm_request)

    assert all(
        msg.get("role") == "user" for msg in messages
    ), f"Expected role 'user' but got {messages}"
    assert any(
        "This is an input text from user." == (msg.get("content") or "")
        for msg in messages
    ), f"Expected the user text to be preserved, but got {messages}"
```

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2458 from TanejaAnkisetty:bug/agent-user-content 381b01418d249b9e6bd91ebb518ff25339a8e47b
PiperOrigin-RevId: 809281620
2025-09-23 15:34:21 -07:00
Google Team Member 632bf8b0bc fix: Filter out thought parts when saving agent output to state
PiperOrigin-RevId: 809270320
2025-09-19 18:58:59 -07:00
Wei Sun (Jack) 6e834d3fac feat(conformance): Skips recording for inner runner of AgentTool in conformance tests
PiperOrigin-RevId: 809252704
2025-09-19 17:36:18 -07:00
Xiang (Sean) Zhou 9be9cc2fee feat: Support static instructions
Static instructions:
Always added to system instructions for context caching

Dynamic instructions:
Added to system instructions when no static instruction exists (for backward compatibility), OR inserted before last batch of continuous user content when static instructions exist

PiperOrigin-RevId: 809170679
2025-09-19 13:46:36 -07:00
Xiang (Sean) Zhou f4e1fd962e chore: Add sample agent for content cache and basic profiling
PiperOrigin-RevId: 809166922
2025-09-19 13:37:57 -07:00
Xiang (Sean) Zhou c66245a3b8 feat: support context caching
1. add a context cache config in app level which will apply to all agents in the app
2. pass on cache config through invocation context to llm_reqeust
3. store cache metadata in llm_response
4. lookup old cache metadata from latest event for reusing old cache
5. create new cache if old cache cannot be reused

PiperOrigin-RevId: 809158578
2025-09-19 13:17:02 -07:00
Xinran (Sherry) Tang 13a95c463d feat: Add get_events util function in invocation_context
PiperOrigin-RevId: 809111315
2025-09-19 11:21:35 -07:00
Kacper Jawoszek f157b2ee4c feat(otel): support standard OTel env variables for exporter endpoints
ADK web server will automatically setup OTel providers with exporters if any of the .*_ENDPOINT variables from https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/ is set.

PiperOrigin-RevId: 809079453
2025-09-19 09:59:58 -07:00
Bastien Jacot-Guillarmod ccd0e12b42 chore: Internal change
PiperOrigin-RevId: 809077633
2025-09-19 09:55:17 -07:00
Kacper Jawoszek 3b80337faf feat(otel): temporarily disable Cloud Monitoring integration in --otel_to_cloud
Currently there is chance for Cloud Monitoring-related errors in logs during shutdown. Let's disable metrics part until it is fixed.

PiperOrigin-RevId: 808930635
2025-09-19 01:28:15 -07:00
Xuan Yang d4eaa06041 chore: update ADK release analyzer agent to use the compare link instead of commit link
PiperOrigin-RevId: 808900352
2025-09-18 23:44:12 -07:00
Xuan Yang 4d39563ea4 chore: add yaml files to the ADK Vertex AI Search datastore
PiperOrigin-RevId: 808895175
2025-09-18 23:27:34 -07:00
Wei Sun (Jack) 006a406f5b chore: Allow outputting non-acsii without escape and excludes fields in the dumped yaml files in the yaml_utils.py
Also excludes `_adk_recordings_config` for `adk conformance create` command.

PiperOrigin-RevId: 808865049
2025-09-18 21:24:14 -07:00
Wei Sun (Jack) f39df4155e feat(conformance): Supports content and state_delta in TestCase.user_messages and initial_state for session creation
PiperOrigin-RevId: 808827170
2025-09-18 18:55:38 -07:00
Hangfei Lin 1a91bb2a59 chore: Update comments in Compaction to clarify timestamp-based ranges
The docstrings for `compaction_range` and `compacted_content` are updated to reflect that compaction is based on timestamp ranges rather than sequence IDs, and to use consistent terminology ("compacted" instead of "summarized").

PiperOrigin-RevId: 808770610
2025-09-18 15:51:40 -07:00
Wei Sun (Jack) 9c2b7091ee refactor(comformance): Improves field comparison logic in replay plugin with nested exclude dict from pydantic v2
Also use `ReplayConfigError` to replace `ValueError`s

PiperOrigin-RevId: 808750606
2025-09-18 15:01:19 -07:00
Nikhil Purwant 21c26f92d4 chore: Added ADK Authentication End2End Samples
Merge https://github.com/google/adk-python/pull/2960

1. All in one authentication sample (has an IDP, Agent and the application) under `contributing/samples/authn-adk-all-in-one/`
2. Documented for all the steps.
3. OAuth 2.0 Authorization Code Grant type used by the agent.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2960 from nikhilpurwant:main dfcc821602d265c4ae7cc42eb1f5739beaad6f87
PiperOrigin-RevId: 808672120
2025-09-18 11:44:21 -07:00
guillaume blaquiere 25958242db feat: add endpoint to generate memory from session
Merge https://github.com/google/adk-python/pull/2900

In relation with #2416

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2900 from guillaumeblaquiere:add-session-to-memory 0507de43021c62f9223167dca8f53b536227ad04
PiperOrigin-RevId: 808658162
2025-09-18 11:13:21 -07:00
Kel Markert 6b49391546 feat: Add Google Maps Grounding Tool to ADK
This add `GoogleMapsGroundingTool`, a built-in tool for Gemini 2 models to ground query results with Google Maps. This tool operates internally within the model and is only available when using the VertexAI Gemini API.

PiperOrigin-RevId: 808650501
2025-09-18 10:54:27 -07:00
Xuan Yang 8a92fd18b6 fix: ignore empty function chunk in LiteLlm streaming response
Fixes https://github.com/google/adk-python/issues/1532

PiperOrigin-RevId: 808636127
2025-09-18 10:18:53 -07:00
Hangfei Lin c37bd2742c feat: Introduce LLM context compaction interface
Provide a more efficient way to compact LLM context for better agentic performance.

* `app`: the top level abstraction for an ADK application. It contains an root agent, and plugins.
* `content_strategy`: the abstraction for selecting the contents for LLM request.
* `compaction_strategy`: the abstraction for compacting the events.
* Added `sequence_id` and `summary_range` in event class.

PiperOrigin-RevId: 808634224
2025-09-18 10:14:12 -07:00
Wei Sun (Jack) e86647d446 feat(conformance): Implements adk conformance test cli with replay mode
PiperOrigin-RevId: 808633566
2025-09-18 10:12:43 -07:00
Afonso Menegola c9ea80af28 fix: Prevent escaping of Latin characters in LLM response
Merge https://github.com/google/adk-python/pull/2937

**Closes #2936**

This Pull Request addresses the issue where `LlmAgent` outputs, when configured with `output_schema` and `tools`, were presenting escaped Latin characters (e.g., `\xf3` for `Ăł`) in the final response. This behavior occurred because `json.dumps` was being called with `ensure_ascii=True` (its default), which is not ideal for human-readable output, especially when dealing with non-ASCII characters common in many languages like Portuguese.

**Changes Proposed:**

* Modified the `_OutputSchemaRequestProcessor` in `src/google/adk/flows/llm_flows/_output_schema_processor.py` to explicitly set `ensure_ascii=False` when calling `json.dumps` for the `set_model_response` tool's output.

**Impact:**

This change ensures that all non-ASCII characters in the structured model response are preserved in their natural form, improving the readability and user experience of agent outputs, particularly for users interacting in languages with accented characters or other special symbols.

**Testing:**

The fix was verified locally by running an `LlmAgent` with an `output_schema` and confirming that responses containing Latin characters (e.g., "ação", "caminhão", "ícone") are now correctly displayed without escaping.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2937 from amenegola:fix/issue-2936-escape-chars 6cac00f97aa4cd8d8ccaa97ec5fffc74f57995dc
PiperOrigin-RevId: 808622892
2025-09-18 09:48:03 -07:00
Xiang (Sean) Zhou 86ee6e3fa3 fix: Close runners after running eval
this fixes https://github.com/google/adk-python/issues/2196

PiperOrigin-RevId: 808618368
2025-09-18 09:36:56 -07:00
Wei Sun (Jack) bf4ff31009 feat(conformance): add CLI (adk conformance create) for generating conformance tests from spec.yaml file
- Add conformance command group with create subcommand
- Implement category/name/spec.yaml with generated-*.yaml files
- Support executing agents with queries and recording sessions
- Create test cases with recorded llm interactions and tool calls/results

Expected folder structure:

```

conformance_repo/
├── agents/                            # Agent definitions - contains all config-based agents shared by test cases.
│   ├── single_basic/
│   ├── multi_basic/
│   └── single_tool_builtin/
│
└── tests/                             # Test cases
    ├── core/                          # Test category
    │   ├── desc_001/                  # Individual test case
    │   │   ├── spec.yaml             # Human-written specification
    │   │   ├── generated-session.yaml
    │   │   ├── generated-recordings.yaml
    │   │   └── ...                   # Potential future generated files
    │   ├── f_001/
    │   │   ├── spec.yaml
    │   │   ├── generated-session.yaml
    │   │   ├── generated-recordings.yaml
    │   │   └── ...

```

Help text:

```
-> % adk conformance create --help
Usage: adk conformance create [OPTIONS] [PATHS]...

  Generate ADK conformance test YAML files from TestCaseInput specifications.

  NOTE: this is work in progress.

  This command reads TestCaseInput specifications from input.yaml files, executes the specified test cases against agents, and generates conformance test files with recorded agent interactions as
  test.yaml files.

  Expected directory structure: category/name/input.yaml (TestCaseInput) -> category/name/test.yaml (TestCase)

  PATHS: One or more directories containing test case specifications. If no paths are provided, defaults to 'tests/' directory.

  Examples:

  Use default directory: adk conformance create

  Custom directories: adk conformance create tests/core tests/tools

Options:
  --help  Show this message and exit.
```
PiperOrigin-RevId: 808609547
2025-09-18 09:14:05 -07:00
Hangfei Lin 4cb07ba05e chore: Update plugins in hello_world_app
Corrected `CountInvocationPlugin` to be a class reference and added `ContextFilterPlugin` to limit the number of tool invocations kept in the context to 3.

PiperOrigin-RevId: 808591608
2025-09-18 08:26:42 -07:00
Kacper Jawoszek cee365a13d feat(otel): Add GenAI Instrumentation if --otel_to_cloud is enabled
PiperOrigin-RevId: 808460137
2025-09-18 01:33:13 -07:00
Wei Sun (Jack) 712da1bd36 feat(conformance): Integrates RecordingsPlugin into AdkWebServer to record Llm interactions and tool calls
When start the server with `--extra_plugins=google.adk.cli.plugins.recordings_plugin.RecordingsPlugin`, it will trigger recording with expected state in session.

PiperOrigin-RevId: 808432022
2025-09-18 00:05:06 -07:00
Xiang (Sean) Zhou 99405d6a8a chore: Fix the starting folder for finding ADK source
PiperOrigin-RevId: 808371099
2025-09-17 20:20:58 -07:00
Hangfei Lin a06bf278cb feat: Adding the ContextFilterPlugin
This commit introduces a new ContextFilterPlugin which allows for filtering the LlmRequest contents before they are sent to the LLM. This helps in managing and potentially reducing the size of the LLM context.

The plugin provides two primary filtering mechanisms:

num_invocations_to_keep: Keeps only the specified number of the most recent user-model invocations. An invocation is defined as one or more user messages followed by a model response.
custom_filter: Allows for a user-defined callable to be applied to the contents for more flexible filtering.
Unit tests have been added to cover the different filtering scenarios, including:

Filtering by the last N invocations.
Filtering using a custom function.
Combining both filtering methods.
Handling cases with multiple user turns in a single invocation.
Ensuring no filtering occurs when options are not provided.
Gracefully handling exceptions from custom filter functions."

For example, when num_of_innovacations=2:
-----------------------------------------------------------
Contents:
{"parts":[{"text":"9"}],"role":"user"}
{"parts":[{"text":"I am sorry, I cannot fulfill this request. I need more information on what you would like me to do. I can roll a die or check prime numbers.\n"}],"role":"model"}
{"parts":[{"text":"1"}],"role":"user"}
{"parts":[{"text":"I am sorry, I cannot fulfill this request. I need more information on what you would like me to do. I can roll a die or check prime numbers.\n"}],"role":"model"}
{"parts":[{"text":"10"}],"role":"user"}
-----------------------------------------------------------
PiperOrigin-RevId: 808355316
2025-09-17 19:28:56 -07:00
Google Team Member 10cf377494 feat: Make the bigquery sample agent run with ADC out-of-the-box
Right now the bigquery sample agent is configured to run with OAuth, which requires some set up. This change makes it more readily usable, both locally and in AgentEngine, as Application Default Credentials (ADC) is easier to set up, and often local and AgentEngine environment already have it set up.

PiperOrigin-RevId: 808315879
2025-09-17 16:52:49 -07:00
Wei Sun (Jack) 3bd2f29f3a feat(conformance): Adds a replay plugin to replay the previously recorded llm/tool recordings for conformance tests
PiperOrigin-RevId: 807979314
2025-09-16 21:54:25 -07:00
Xiang (Sean) Zhou 14f118899d chore: Add example agent to get log probabilitis
see https://github.com/google/adk-python/issues/2764

PiperOrigin-RevId: 807972596
2025-09-16 21:23:21 -07:00
Wei Sun (Jack) c0554e4b13 feat(conformance): add an ADK plugin to record Llm request/response and tool call/result to recordings.yaml file
Also moves the `Recordings` pydantic models into this plugins/ package.

Key features:
- Records LLM requests/responses and tool calls/results to YAML files in `generated-recordings.yaml`.
- Use session state to determine where to read and output recordings.

PiperOrigin-RevId: 807969100
2025-09-16 21:10:09 -07:00
Google Team Member 6bd33e1be3 fix: Retain the consumers and transport registry when recreating the ClientFactory in remote_a2a_agent.py
PiperOrigin-RevId: 807762203
2025-09-16 10:58:46 -07:00
Xiang (Sean) Zhou f7bd3c111c feat: Expose log probs of candidates in LlmResponse
fixes https://github.com/google/adk-python/issues/2764

PiperOrigin-RevId: 807516910
2025-09-15 21:36:15 -07:00
Wei Sun (Jack) 1ce043a278 chore: Fixes BasePlugin#after_run_callback return type hint
`Optional[None]` is `Union[None, None]`, which is essentially None.

PiperOrigin-RevId: 807515970
2025-09-15 21:33:05 -07:00
Xuan Yang bd21847295 chore: add a step to load adk-bot SSH Private Key for the release analysis workflow
PiperOrigin-RevId: 807479079
2025-09-15 19:20:36 -07:00
Kacper Jawoszek 1ae0b82f56 feat(otel): add --otel_to_cloud experimental support
Cloud Trace, Cloud Monitoring and Cloud Logging integrations are set up via OTel if otel_to_cloud CLI param/fast_api arg is provided.

This is similar to current Cloud Trace integration via trace_to_cloud, just extended to Monitoring and Logging as well.

PiperOrigin-RevId: 807385680
2025-09-15 14:32:22 -07:00
Xiang (Sean) Zhou d6d4b144e9 chore: Update instructions not to ask for root folder if user doesn't intent to create or implement an agent
PiperOrigin-RevId: 807372074
2025-09-15 13:59:08 -07:00
Xinran (Sherry) Tang 4dbec15d26 test: Add unittest suites for testing HITL confirmation flow on runner level
PiperOrigin-RevId: 807327997
2025-09-15 12:00:49 -07:00
Wei Sun (Jack) 402f3626b3 feat(conformance): Replaces invocation_id with user_message_index in the Recording
`invocation_id` is per-request, so we just need user_message_index to help locate where to start replay.

PiperOrigin-RevId: 807300016
2025-09-15 10:49:13 -07:00
Google Team Member 6158075a65 fix: introduces a raw_mcp_tool method in McpTool to provide direct access to the underlying MCP tool
PiperOrigin-RevId: 807299777
2025-09-15 10:48:13 -07:00
Google Team Member b1312680f4 feat(otel): add --otel_to_cloud experimental support
Cloud Trace, Cloud Monitoring and Cloud Logging integrations are set up via OTel if otel_to_cloud CLI param/fast_api arg is provided.

This is similar to current Cloud Trace integration via trace_to_cloud, just extended to Monitoring and Logging as well.

PiperOrigin-RevId: 807285744
2025-09-15 10:11:12 -07:00
Google Team Member 103e88e95f test: Add evaluation for BigQuery tools
We should treat this as the first step towards building a robust eval story for BQ tools.

PiperOrigin-RevId: 807247053
2025-09-15 08:16:33 -07:00
Kacper Jawoszek 7870480c63 feat(otel): add --otel_to_cloud experimental support
Cloud Trace, Cloud Monitoring and Cloud Logging integrations are set up via OTel if otel_to_cloud CLI param/fast_api arg is provided.

This is similar to current Cloud Trace integration via trace_to_cloud, just extended to Monitoring and Logging as well.

PiperOrigin-RevId: 807230668
2025-09-15 07:22:19 -07:00
Bastien Jacot-Guillarmod b9735b2193 docs: Correct the documentation of after_agent_callback
The `after_agent_callback` in plugin works similarly as the `after_agent_callback` in `base_agent.py`, e.g. it only append new content, but cannot modify the previous content.

PiperOrigin-RevId: 807162139
2025-09-15 03:06:57 -07:00
Wei Sun (Jack) 8ec83d6c18 feat(conformance): Add data definitions used to create adn run conformance tests
PiperOrigin-RevId: 807100057
2025-09-14 23:30:44 -07:00
Xiang (Sean) Zhou 6ab87da592 chore: Add back the request logging in RemoteA2aAgent given the logging was already fixed
PiperOrigin-RevId: 806551434
2025-09-12 22:40:58 -07:00
Wei Sun (Jack) b53e6e3567 chore: bump version to 1.14.1 with a patch for A2A logging issue
Prepare a patch version for #2918

PiperOrigin-RevId: 806537425
2025-09-12 21:29:58 -07:00
Google Team Member c29d41f0d0 feat: add Spanner similarity_search tool
Similarity search tool supports similarity search on Spanner data by embedding a text query to a vector and run vector search with the embedded vector.

PiperOrigin-RevId: 806502499
2025-09-12 18:49:50 -07:00
Google Team Member 0c1f1fadeb fix: Fix logging issues with RemoteA2aAgent
Recent change to the updated A2A Client SDK broke the logging utilities. This updates those logging utilities to work with the new A2A SDK structure.

PiperOrigin-RevId: 806482017
2025-09-12 17:20:04 -07:00
Google Team Member bb148002f8 fix: Filter out thought parts when saving agent output to state
PiperOrigin-RevId: 806478056
2025-09-12 17:05:26 -07:00
Google Team Member 4c00b86e33 feat: Provide location config for BigQuery tools
Right now the tolls are always running against multi-region US by default. With this change the agent builder can scope the tools to data and compute in a particular BigQuery location.

PiperOrigin-RevId: 806473857
2025-09-12 16:52:16 -07:00
Xuan Yang b3b31a9ffb chore: add a main.py script for the ADK docs updater agent
PiperOrigin-RevId: 806468319
2025-09-12 16:33:06 -07:00
Hangfei Lin 463dcee58c chore: specify the default sides for roll dice agent in bidi
PiperOrigin-RevId: 806468232
2025-09-12 16:32:10 -07:00
Google Team Member 4f07228f57 chore: Move framework filled params to the end in the BigQuery forecast tool
This is for better readability of the tool, specially in relation to the examples in the docstring.

PiperOrigin-RevId: 806460056
2025-09-12 16:03:57 -07:00
Google Team Member c53c02f022 chore: add clientIdEnum for CA API usage tracking
PiperOrigin-RevId: 806453560
2025-09-12 15:44:28 -07:00
Hangfei Lin 4e6b31a860 chore: Improve bug report template for Google ADK
Update the bug report issue template to request minimal reproducible examples, error/stacktrace, clarify OS options, and include questions about LiteLLM usage and specific model details.

PiperOrigin-RevId: 806435953
2025-09-12 14:53:03 -07:00
Hangfei Lin afebb5227b chore: Update ADK Live documentation on handling audio and transcriptions
Add guidelines for saving transcriptions as session Events and audio as artifacts with references in Events.

PiperOrigin-RevId: 806424916
2025-09-12 14:20:02 -07:00
Hangfei Lin 168c724866 test: Add test to ensure RunConfig instances do not share audio transcription configs
The new test verifies that `output_audio_transcription` and `input_audio_transcription` attributes are unique to each `RunConfig` instance, preventing unintended side effects from modifying one instance.

PiperOrigin-RevId: 806405671
2025-09-12 13:26:31 -07:00
Xiang (Sean) Zhou 05e3f73451 chore: Remove _in_memory_session_service from InMemoryRunner
PiperOrigin-RevId: 806385604
2025-09-12 12:29:23 -07:00
Hangfei Lin 23834e8a02 chore: Remove unused _get_audio_transcription_from_session function
This function is no longer called or needed within the `BaseLlmFlow` class.

PiperOrigin-RevId: 806351470
2025-09-12 11:02:37 -07:00
Xuan Yang de1c889a83 chore: create an initial ADK docs updater agent to create doc update PRs
PiperOrigin-RevId: 806348675
2025-09-12 10:55:36 -07:00
Hangfei Lin 2d98b2c30f chore: Update default model in live bidi streaming sample
Switched the active model from `gemini-live-2.5-flash-preview` (for AI Studio) to `gemini-2.0-flash-live-preview-04-09` (for Vertex).

PiperOrigin-RevId: 806348640
2025-09-12 10:54:41 -07:00
Xuan Yang 4cf00702a0 chore: re-structure adk_documentation folder so that agents in it can share the common files
PiperOrigin-RevId: 806348410
2025-09-12 10:53:44 -07:00
Hangfei Lin a7f4e02dc7 chore: Clarify that LLMResponse.content should only contain user/model-generated content
PiperOrigin-RevId: 806157090
2025-09-12 00:19:21 -07:00
Hangfei Lin 908757b47f chore: Add Tool Confirmation to README
This change updates the open-source workspace README to include "Tool Confirmation" in the list of new features.

PiperOrigin-RevId: 806127595
2025-09-11 22:34:01 -07:00
Wei Sun (Jack) 91528890db chore: Adds indent to YAML sequence by default for better visual readability
Both are valid YAML, just with indent, it's more visually friend to see the data structure hierarchy.

Before

```
items:
- item1
- item2
- item3
```

After

```
items:
  - item1
  - item2
  - item3
```
PiperOrigin-RevId: 806117290
2025-09-11 21:59:20 -07:00
Hangfei Lin f73ae6e101 chore: Remove redundant attribute descriptions from docstrings
The attributes are already defined as fields in the Pydantic models, making the docstring descriptions unnecessary.

PiperOrigin-RevId: 806091305
2025-09-11 20:15:19 -07:00
Google Team Member 9862b7b1e2 fix: Remove the logging method in remote a2a agent lib which is expecting a wrong type
The a2a_request is in type Message where the function expecting SendMessageRequest type

PiperOrigin-RevId: 806001430
2025-09-11 15:09:00 -07:00
Hangfei Lin ab69ef8de8 feat: Move livebidi agents esp multi-agent to use session/events
The old live/bidi agents are using a cache to store context/history during agent transfer etc. As we have added support for session for live/bidi, we are now migrating the context/history cache to it. This improves scalability, efficiency and maintainability.

It introduces several changes:
* AudioTranscriber support is removed as now we are using native transcription from models.
* Transcription is returned as input_transcription/output_transcription fields and no longer as contents.
* We will return a new event with artifact references of file type of audio/pcm.(in addition to existing audio response event. So the users of this api need to do proper filtering here.)

PiperOrigin-RevId: 805997675
2025-09-11 14:58:33 -07:00
Hangfei Lin 873551d7b9 chore: Update model references in README
Changed all instances of "gemini-2.0-flash" to "gemini-2.5-flash" in the example code snippets within the README.

PiperOrigin-RevId: 805949871
2025-09-11 12:48:39 -07:00
Xuan Yang 921e5cb370 ci: minor fix for the "bot responded" label for the discussion answering agent
PiperOrigin-RevId: 805905926
2025-09-11 10:56:43 -07:00
Xuan Yang f52608328e ci: fix discussion answering agent main.py by removing the redundant json import
PiperOrigin-RevId: 805879980
2025-09-11 09:56:38 -07:00
Ankur Sharma c5613fb6f0 feat: Add Rubrics to EvalCase datamodel
For advanced eval use cases, we do expect agent developers to have rubrics that are specific to an Eval Case and in some cases even specific to a single invocation/turn in the eval case conversation.

A separate PR will be created to consume this data model changes in ADK Eval.

PiperOrigin-RevId: 805588808
2025-09-10 18:00:15 -07:00
Xiang (Sean) Zhou 0bc2ee64e3 ci: Fix discussion answering agent
a. dump the discussion content to a tmp file first to avoid github redaction of environment variable
b. instruct the agent to use get_discussion_and_comments only when discussion content json is not available.

PiperOrigin-RevId: 805581573
2025-09-10 17:33:54 -07:00
Xuan Yang f96f0ebd0d chore: add issues: write permission for the ADK release analysis Github workflow
PiperOrigin-RevId: 805563540
2025-09-10 16:36:27 -07:00
Hangfei Lin 894bec794e chore: Update default and example Gemini models to new versions
Changes references from `gemini-1.5-flash` and `gemini-1.5-pro` to `gemini-2.5-flash` and `gemini-2.5-pro` in docstrings, default values, sample agents, and tests.

PiperOrigin-RevId: 805536434
2025-09-10 15:22:52 -07:00
Hangfei Lin 3c433b7168 chore: bidi streaming example on run live fast api
This sample connects to adk agent api server with websocket, to exchange streaming audio/text.

PiperOrigin-RevId: 805531120
2025-09-10 15:08:26 -07:00
Hangfei Lin 707c1a7bd4 ADK changes
PiperOrigin-RevId: 805523988
2025-09-10 14:49:25 -07:00
Shangjie Chen 97cf724f14 chore: Release ADK 1.14.0
PiperOrigin-RevId: 805506354
2025-09-10 14:04:22 -07:00
Ankur Sharma e88e667770 feat: Data model for Rubric based metric and eval config
Details:
- We plan on introducing Rubric based metrics in subsequent changes. This change introduces the data model needed that allows agent developer to provide rubrics.

- We also introduce a data model for the config that the eval system has been using for quite some time. It was loosely and informally described as a dictionary of metric names and expected thresholds. In this change, we actually formalize it using a pydantic data model, and extend it allow developers to specify rubrics as a part of their eval config.

What is a rubric based metric?
A rubric based metric is the assessment of a Agent's response (final or intermediate) along some rubric. This evaluation of agent's response significantly differs from the strategy where one has to provide a golden response.

PiperOrigin-RevId: 805488436
2025-09-10 13:20:07 -07:00
George Weale 37228beddd fix: Enable saving input blobs as artifacts in ADK web server for issue #2176
The `run_config` for `run_agent` now includes `save_input_blobs_as_artifacts=True`.

PiperOrigin-RevId: 805472895
2025-09-10 12:39:42 -07:00
Xuan Yang 957dc628ab chore: set up Github workflow for ADK release analyzer for doc updates
PiperOrigin-RevId: 805434018
2025-09-10 11:02:59 -07:00
Hangfei Lin 7148e0e82e test: Add tests for Runner initialization constraints
These tests verify that `ValueError` is raised when `Runner` is initialized without providing either an `app` instance or both `app_name` and `agent`.

PiperOrigin-RevId: 805427256
2025-09-10 10:48:33 -07:00
Google Team Member 0935a40011 feat: Add Bigquery Forecast tool
This tool answers questions about structured data in BigQuery using natural language.

PiperOrigin-RevId: 805414952
2025-09-10 10:20:47 -07:00
Xuan Yang 3b428ec81f chore: let adk-bot respond to discussion when it is tagged
PiperOrigin-RevId: 805406204
2025-09-10 10:02:23 -07:00
GenkiNoguchi 5cda37adb3 chore: fix typos in multiple files
Merge https://github.com/google/adk-python/pull/2864

**Reason for this change:**

  Multiple typos were found in comments, docstrings, and code throughout the codebase, which could lead to confusion and reduce code readability.

  **Changes made:**

  Fixed the following typos across 8 files:

  1. contributing/samples/adk_answering_agent/utils.py:130: "extention" → "extension"
  2. llms-full.txt:15171: "fuction" → "function"
  3. src/google/adk/a2a/converters/part_converter.py:
    - Line 96: "Conver" → "Convert", "reponse" → "response"
    - Line 99: "suervice" → "service"
    - Line 100: "accordinlgy" → "accordingly"
    - Line 191: "Conver" → "Convert", "reponse" → "response"
    - Line 195: "accordinlgy" → "accordingly"
  4. src/google/adk/agents/base_agent.py:568: "custome" → "custom"
  5. src/google/adk/evaluation/agent_evaluator.py:572: "Retruns" → "Returns"
  6. src/google/adk/flows/llm_flows/basic.py:55: "outoput_schema" → "output_schema"
  7. src/google/adk/flows/llm_flows/contents.py:136: "fuction_response" → "function_response"
  8. src/google/adk/models/google_llm.py:138: "gemini_llm_connecton.py" → "gemini_llm_connection.py"

  **Impact:**

  This change will:
  - Improve code documentation clarity and professionalism
  - Make comments, docstrings, and code more readable and accurate
  - Help prevent confusion for developers reading the code
  - Ensure consistency in terminology throughout the codebase

  This is a non-breaking change that only affects comments, documentation strings, and improves code clarity.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2864 from ammmr:chore-fix-typos 3cea9fcf6f21edb006b63e9258d2b82930dd961d
PiperOrigin-RevId: 805227784
2025-09-10 00:08:15 -07:00
Google Team Member 3e6d91f9e2 docs: Update description of task_completed function in SequentialAgent
PiperOrigin-RevId: 805223251
2025-09-09 23:53:14 -07:00
Xuan Yang 8132d3b621 chore: add instructions for the ADK release analyzer agent to sort the recommended changes and recommend API reference changes
PiperOrigin-RevId: 805099909
2025-09-09 16:07:28 -07:00
Xiang (Sean) Zhou 43c96811da ci: Fix discussion answering github action workflow to escape the quote in the discussion content JSON
PiperOrigin-RevId: 805091905
2025-09-09 15:42:34 -07:00
Xuan Yang e3422c616d chore: create an initial ADK release analyzer agent to find the doc updates needed between releases
PiperOrigin-RevId: 805030050
2025-09-09 13:00:05 -07:00
Hangfei Lin 8174a29c6d chore: update contribution guide
PiperOrigin-RevId: 804985449
2025-09-09 11:09:40 -07:00
Google Team Member a645580aa6 ADK changes
PiperOrigin-RevId: 804937691
2025-09-09 09:11:08 -07:00
Xuan Yang 78eea1aa55 chore: skip PR triage for already triaged or Google-contributor PRs
The `agent-triage-pull-request` job will now only run if the pull request does not have the 'bot triaged' or 'google-contributor' labels, avoiding redundant and unnecessary triage actions.

PiperOrigin-RevId: 804732073
2025-09-08 22:20:19 -07:00
Google Team Member fa55354a1a feat: Update to ADK + A2A Remote Client to use A2A SDK ClientFactory
Use the A2A Python SDK for client support for A2A Remote clients. This enables A2A based agents that use gRPC or RESTful interfaces, as well as the jsonrpc support. This also simplifies creation of clients and provides simpler mechanisms to inject credentials and observability into the remote agent interactions.

PiperOrigin-RevId: 804711466
2025-09-08 21:03:27 -07:00
Google Team Member 64f11a6a67 chore: Avoid mutable default arguments in local_eval_service and runners
Changed default values for `session_service`, `artifact_service`, and `run_config` from instances of mutable classes to `None`. Instances are now created within the function body if the argument is not provided, preventing unexpected shared state across function calls.

PiperOrigin-RevId: 804624564
2025-09-08 16:11:24 -07:00
George Weale d56dd08072 fix: Enable saving input blobs as artifacts in ADK web server for issue #2176
The `run_config` for `run_agent` now includes `save_input_blobs_as_artifacts=True`.

PiperOrigin-RevId: 804589111
2025-09-08 14:30:03 -07:00
Shangjie Chen 8452d2bcba feat: Allow function tool to pass in a callable to decide whether it need confirmation
PiperOrigin-RevId: 804583437
2025-09-08 14:16:59 -07:00
George Weale 43eec82f84 fix: Add a NOTE to agent transfer instructions listing available agents
The system instructions for agent transfer now include a NOTE section that lists all agents available for the `transfer_to_agent` function. This also has the target agents and, if there is one that applies, the parent agent. New unit tests are added to verify the correct generation of this NOTE.

PiperOrigin-RevId: 804569691
2025-09-08 13:43:38 -07:00
George Weale 5b465fd71b chore: Avoid mutable default arguments in local_eval_service and runners
Changed default values for `session_service`, `artifact_service`, and `run_config` from instances of mutable classes to `None`. Instances are now created within the function body if the argument is not provided, preventing unexpected shared state across function calls.

PiperOrigin-RevId: 804560641
2025-09-08 13:21:05 -07:00
George Weale ca5f7f1ff0 chore: Reorder dependencies in pyproject.toml
PiperOrigin-RevId: 804559734
2025-09-08 13:18:41 -07:00
Yujun Zou 467df1a36f docs: Update root_agent description for clarity
Update description as: Coordinator agent to greet users.

PiperOrigin-RevId: 804553925
2025-09-08 13:01:47 -07:00
Google Team Member 72ff9c64a2 feat: Add GkeCodeExecutor for sandboxed code execution on GKE #non-breaking
Merge https://github.com/google/adk-python/pull/1629

close https://github.com/google/adk-python/issues/2170

### Summary

This PR introduces `GkeCodeExecutor`, a new code executor that provides a secure and scalable method for running LLM-generated code by leveraging GKE Sandbox. It serves as a robust alternative to local or standard containerized executors by leveraging the **GKE Sandbox** environment, which uses gVisor for workload isolation.

For each code execution request, it dynamically creates an ephemeral Kubernetes Job with a hardened Pod configuration, offering significant security benefits and ensuring that each code execution runs in a clean, isolated environment.

### Key Features of GkeCodeExecutor

* **Dynamic Job Creation**: Uses the Kubernetes `batch/v1` API to create a new Job for each code snippet.
* **Secure Code Mounting**: Injects code into the Pod via a temporary `ConfigMap`, which is mounted to a read-only file.
* **gVisor Sandboxing**: Enforces execution within a `gvisor` runtime for kernel-level isolation.
* **Hardened Security Context**: Pods run as non-root with all Linux capabilities dropped and a read-only root filesystem.
* **Resource Management**: Applies configurable CPU and memory limits to prevent abuse.
* **Automatic Cleanup**: Uses the `ttl_seconds_after_finished` feature on Jobs for robust, automatic garbage collection of completed Pods and Jobs.
* **Node Scheduling**: The executor uses Kubernetes `tolerations` in its Pod specification. This allows the k8s scheduler to place the execution Pod onto a **_pre-configured_** gVisor-enabled node.
* **Module Integration**: The `GkeCodeExecutor` is registered in the `code_executors/__init__.py`, making it available for use by agents. The `ImportError` handling is configured to check for the required `kubernetes` SDK.

### Execution Flow:

1.  Agent invokes `GkeCodeExecutor` with the LLM-generated code.
2.  The `GkeCodeExecutor` will `execute_code` – creates a temporary `ConfigMap`, and then create a k8s `Job` to run it.
3.  This Job runs a standard `python:3.11-slim` container. The image is pulled once to the node and cached. The Job will mount the ConfigMap as `/app/code.py`
4.  The GkeCodeExecutor will monitor the Job to completion, fetch `stdout/stderr` logs from the container, return `CodeExecutionResult` to the LlmAgent, and ensure all temp resources are deleted.
5.  The calling agent formats the result and provides a final response to the user. If the result contains error, it will retry up to `error_retry_attempts` times.

PiperOrigin-RevId: 804511467
2025-09-08 11:15:29 -07:00
Shangjie Chen e63fe0c0eb fix: Fix pagination of list_sessions in VertexAiSessionService
Resolves https://github.com/google/adk-python/issues/2860

PiperOrigin-RevId: 804511401
2025-09-08 11:14:32 -07:00
Max Ind bc6b5462a7 test: add functional telemetry tests
This includes:
- Test verifying multiple spans are written during E2E runner execution.
- Regression tests for the "ContextVar was created in a different Context" exceptions caused by the interplay of context based instrumentation and async generators getting indeterminately suspended.

PiperOrigin-RevId: 804333483
2025-09-08 02:23:10 -07:00
George Weale 1e23652968 fix: AttributeError and indentation in parameter processing. For issue #2776 and issue #2763
PiperOrigin-RevId: 804222317
2025-09-07 18:37:42 -07:00
Google Team Member 1979dcf496 fix: Allow AgentTool to inherit/use plugins from its invocation context when running
PiperOrigin-RevId: 803656189
2025-09-05 17:09:04 -07:00
Hangfei Lin fc90ce968f test: Add unit tests for the App class and improve Runner initialization tests
-   Added `tests/unittests/apps/test_apps.py` with basic tests for `App` initialization.
-   Modified `tests/unittests/test_runners.py` to include a test that verifies `Runner` raises a `ValueError` when both `app` and `app_name` are provided during initialization.

PiperOrigin-RevId: 803556826
2025-09-05 12:16:38 -07:00
Hangfei Lin decc19b188 chore: Update release cadence in README
The release cadence is now described as "roughly bi-weekly" instead of "weekly".

PiperOrigin-RevId: 803528472
2025-09-05 11:03:05 -07:00
Xiang (Sean) Zhou 25df6c22d5 chore: Tune instructions to not ask root directory if it's already provided in the context
PiperOrigin-RevId: 803512675
2025-09-05 10:23:34 -07:00
Google Team Member 45c1fcc84f feat: disallow setting non-existent properties in BigQuery tools and credentials config
This will save the agent builder getting wrong impression if by mistake they set a property that does not exist.

PiperOrigin-RevId: 803208559
2025-09-04 15:58:19 -07:00
Wei Sun (Jack) ebf2c98e41 feat(conformance): Adds a minimal AdkWebServer http client for conformance tests to interact with
PiperOrigin-RevId: 803208215
2025-09-04 15:56:53 -07:00
Hangfei Lin 7b077ac351 chore: Add community repo dependency group to pyproject toml
PiperOrigin-RevId: 803191617
2025-09-04 15:11:09 -07:00
Google Team Member b05fef9ba7 feat: Allow custom part converters in A2A classes
This change introduces type descriptions for the functions which convert between A2A and GenAI `Part`s. It then allows passing instances of those functions to the various A2A-related functions/classes, effectively allowing users to inject their own logic for how part conversion should occur.

The benefit of this pattern is that users can create decorators around the core `Part` conversion logic, which allows them to intercept the cases they care about while delegating the ones they do not to the core converter. This is a pattern we use a lot in the A2A Python SDK.

One example where this type of logic is useful is for extensions: this allows extension logic to, for example, interpret an A2A DataPart into a FunctionResponse using extension-specific logic.

PiperOrigin-RevId: 803186799
2025-09-04 14:57:15 -07:00
Hangfei Lin 4df79dd5c9 feat: Upgrade ADK stack to use App instead in addition to root_agent
The convention:
- If some fields(like plugin) are defined both at root_agent and app, then a error will be raised.
- app code should be located within agent.py.
- an instance named app should be created

PiperOrigin-RevId: 803155804
2025-09-04 13:38:00 -07:00
Wei Sun (Jack) 14484065c6 chore: Follow pydantic convention to make field_validator a public method
PiperOrigin-RevId: 802861986
2025-09-03 22:36:25 -07:00
Che Liu 7720616c5f chore: Update comment to clarify after_run callbacks
PiperOrigin-RevId: 802852137
2025-09-03 22:01:27 -07:00
Shangjie Chen cecf7e805d fix: Support saving text artifacts in GCS artifact service
Resolves https://github.com/google/adk-python/issues/2775

PiperOrigin-RevId: 802850139
2025-09-03 21:55:07 -07:00
Mark Scannell edda922791 feat: add audience and prompt as configurable for OAuth flows
Merge https://github.com/google/adk-python/pull/2738

Some OAuth servers require audience such as [Jira](https://developer.atlassian.com/cloud/confluence/oauth-2-3lo-apps/). This change allows the configuration of audience and prompt (if it needs to be changed) and adds some tests.

This is for issue [2755](https://github.com/google/adk-python/issues/2755).

Resolves #2755

Happy to provide changes/updates if needed.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2738 from mescanne:oauth-audience-prompt 87ce1100792d9156ada2a004bcfaf2fe5fc69602
PiperOrigin-RevId: 802850034
2025-09-03 21:53:54 -07:00
Xiang (Sean) Zhou a1679dae3f feat: Allow users to pass their own agent card to to_a2a method
PiperOrigin-RevId: 802763510
2025-09-03 16:54:33 -07:00
Wei Sun (Jack) a30851ee16 fix: Fixes thought handling in contents.py and refactors its unit tests
Before this change, other agent's reply with thought will still be inserted in the outgoing LlmRequest due to the wrong `else` statement for calling all other type of part.

This commit also refactors test_contents.py to be behavior-oriented tests, instead of implementation-oriented, and add more test cases to cover expected scenarios.

The tests are divided into the following files with different focus:

- test_contents.py: covers the basic logic of event filter;
- test_contents_branch.py: covers the behavior related to branch, which takes effect when ParallelAgent is used.
- test_contents_other_agent.py: covers the retelling behavior to include other agents' reply as context for the current agent.
- test_contents_function.py: covers the function_call/function_response rearrangement logic mainly for `LongRunningFunctionTool`.

PiperOrigin-RevId: 802759821
2025-09-03 16:42:20 -07:00
Wei Sun (Jack) fe8b37b0d3 fix(planner): Fixes the thought field handling in _planning.py
Before this change: `thought` flags was incorrectly removed if the current agent enables BuiltInPlanner.

After this change:

- When it's BuiltInPlanner, keep the thought flag in content history, so that model has full context of its previous thinking.
- When it's PlanReactPlanner, removes the `thought` flag in content history, so that model sees as-is when the content was generated.

PiperOrigin-RevId: 802737130
2025-09-03 15:41:29 -07:00
Xiang (Sean) Zhou 578fad7034 feat: Allow agent loader to load built-in agents from special directories in adk folder
PiperOrigin-RevId: 802716848
2025-09-03 14:48:22 -07:00
pguerra-ce a3410fab7b fix: Pass state_delta to runner in /run endpoint
Merge https://github.com/google/adk-python/pull/2791

Fixes #2789

## Summary
Forward `state_delta` from the FastAPI `/run` request to `Runner.run_async(...)`, aligning behavior with the documented
API and the `/run_sse` endpoint.

## Why
The documentation for `/run` explicitly includes:
> `state_delta` (object, optional): A delta of the state to apply before the run.

However, the non‑SSE `/run` handler did not pass this value through, so `Runner.run_async` always received `None`. The
`/run_sse` path already forwarded it correctly.

## Changes
- `src/google/adk/cli/adk_web_server.py`
    - Add `state_delta=req.state_delta` to the "/run" handler’s `runner.run_async(...)` call.
- `tests/unittests/cli/test_fast_api.py`
    - Add `test_agent_run_passes_state_delta` to test the fix.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2791 from pguerra-ce:fix-state-delta-missing-in-run 83eec8d28b80757e24ae900285eb59530863adbd
PiperOrigin-RevId: 802703072
2025-09-03 14:13:19 -07:00
Xiang (Sean) Zhou b4310727d9 chore: Use lazy % formatting in logging functions to fix pylint warnings
PiperOrigin-RevId: 802639682
2025-09-03 11:35:49 -07:00
Xiang (Sean) Zhou 66cc98801a chore: Adjust the instruction of agent builder assistant for how to use google_search tool and url_context tool
PiperOrigin-RevId: 802629718
2025-09-03 11:14:45 -07:00
Google Team Member 49acad1252 ADK changes
PiperOrigin-RevId: 802455693
2025-09-03 01:50:08 -07:00
Alejandro Cruzado-Ruiz 455dcbda4c ADK changes
PiperOrigin-RevId: 802410800
2025-09-02 22:52:51 -07:00
Shangjie Chen fb009d8ea6 fix: Add custom_metadata to DatabaseSessionService
Resolve https://github.com/google/adk-python/issues/2677

PiperOrigin-RevId: 802375768
2025-09-02 20:09:46 -07:00
Google Team Member aad153322e docs: update the ask_data_insights docstring
PiperOrigin-RevId: 802362601
2025-09-02 19:21:04 -07:00
Shangjie Chen 219815d2d7 chore: Update create_session endpoint to use Request message as post body
Also deprecate create_session_with_id which is not very RESTful.

PiperOrigin-RevId: 802357718
2025-09-02 18:56:45 -07:00
Xiang (Sean) Zhou a503a0c807 ci: Load discussion data from event content to avoid additional GraphQL API call
PiperOrigin-RevId: 802308383
2025-09-02 15:22:17 -07:00
Xiang (Sean) Zhou 408d3dfeb1 chore: refactor discussion answering agent to merge answer_discussions.py into main.py
mainly to dedup duplicated functionality in both file.

PiperOrigin-RevId: 802291102
2025-09-02 14:25:32 -07:00
Google Team Member 831e2e6d4d ADK changes
PiperOrigin-RevId: 801284664
2025-08-30 11:08:43 -07:00
Hangfei Lin dff733c6fc feat: Upgrade ADK stack to use App instead in addition to root_agent
The convention:
- If some fields(like plugin) are defined both at root_agent and app, then a error will be raised.
- app code should be located within agent.py.
- an instance named app should be created

PiperOrigin-RevId: 801252329
2025-08-30 08:01:53 -07:00
Xiang (Sean) Zhou 67f23df25a feat: Allow user specify embedding model for file retrieval
And use Gemini embedding model as default model if no embedding model is specified.

PiperOrigin-RevId: 801161505
2025-08-29 23:35:25 -07:00
Shangjie Chen 0c87907bcb fix: Enforce foreign key constraint for SQLite DB
Resolves https://github.com/google/adk-python/issues/2752

PiperOrigin-RevId: 801106660
2025-08-29 19:07:22 -07:00
Google Team Member 214f2884f5 feat: Upgrade ADK stack to use App instead in addition to root_agent
The convention:
- If some fields(like plugin) are defined both at root_agent and app, then a error will be raised.
- app code should be located within agent.py.
- an instance named app should be created

PiperOrigin-RevId: 801103084
2025-08-29 18:49:04 -07:00
Hangfei Lin a2e89a22a5 feat: Upgrade ADK stack to use App instead in addition to root_agent
The convention:
- If some fields(like plugin) are defined both at root_agent and app, then a error will be raised.
- app code should be located within agent.py.
- an instance named app should be created

PiperOrigin-RevId: 801084463
2025-08-29 17:33:38 -07:00
Xiang (Sean) Zhou 98b0426cd2 chore: Make UT of a2a consistent about how tests should be skipped when python verison < 3.10
PiperOrigin-RevId: 801040421
2025-08-29 14:59:27 -07:00
Google Team Member 2eddc5e4d3 feat: allow setting compute project for BigQuery tools
This will allow restricting BigQuery SQL executions to the specified project. The agent/LLM should resolve the `project_id` param for tools like `execute_sql` and sometimes they can resolve it to an unexpected value due to hallucination or ambiguity. This guardrail will protect against that situation.

PiperOrigin-RevId: 801039685
2025-08-29 14:56:47 -07:00
Shangjie Chen a17bcbb2aa feat: Add a tool confirmation flow that can guard tool execution with explicit confirmation and custom input
The existing `LongRunningTool` does not define a programmatic way to provide & validate structured input, also it relies on LLM to reason and parse the user's response.

For a quick start, annotate the function with `FunctionTool(my_function, require_confirmation=True)`. A more advanced flow is shown in the `human_tool_confirmation` sample.

The new flow is similar to the existing Auth flow:
- User request a tool confirmation by calling `tool_context.request_confirmation()` in the tool or `before_tool_callback`, or just using the `require_confirmation` shortcut in FunctionTool.
- User can provide custom validation logic before tool call proceeds.
- ADK creates corresponding RequestConfirmation FunctionCall Event to ask user for confirmation
- User needs to provide the expected tool confirmation to a RequestConfirmation FunctionResponse Event.
- ADK then checks the response and continues the tool call.

PiperOrigin-RevId: 801019917
2025-08-29 13:56:54 -07:00
Xiang (Sean) Zhou 3ed9097983 chore: Add initial version of agent builder assistant that assists user to build config based agent
PiperOrigin-RevId: 801014241
2025-08-29 13:42:31 -07:00
George Weale 9291daaa8e chore: Add warning for using Gemini models via LiteLLM
Recommend to use Gemini outside of LiteLLM

PiperOrigin-RevId: 800971705
2025-08-29 11:32:45 -07:00
Google Team Member fcd748e17f chore: add contributing Spanner tools RAG agent sample
PiperOrigin-RevId: 800938492
2025-08-29 10:00:43 -07:00
Xiang (Sean) Zhou bb4cfdec12 fix: inject artifact into instructions
a. complain when artifact is None
b. inject None value as empty string instead of `None`

PiperOrigin-RevId: 800930613
2025-08-29 09:38:01 -07:00
George Weale e45c3be238 fix: send full MIME types for image/video/pdf in get_content
Use full media types (image/jpeg, video/mp4, application/pdf) instead of suffixes (jpeg/mp4/pdf) when constructing LiteLLM payloads
This fxes compatibility with providers that validate media types (Anthropic)
Updated and added unit tests to assert full MIME types for image/video/pdf

PiperOrigin-RevId: 800685204
2025-08-28 18:02:18 -07:00
Google Team Member 11a2ffe35a feat: allow setting agent/application name for BigQuery tools
This will allow tracking of tool usage per agent/application.

PiperOrigin-RevId: 800607186
2025-08-28 14:10:01 -07:00
Jinning Li f4a8df0ba2 feat:Add tool_responses to IntermediateData
PiperOrigin-RevId: 800600571
2025-08-28 13:55:15 -07:00
Wei Sun (Jack) 8e43f0dd83 fix(deploy): Add back installing requirements.txt to Dockerfile template for cloud run
PiperOrigin-RevId: 800595427
2025-08-28 13:43:03 -07:00
Xiang (Sean) Zhou b92b288c97 chore: fix flaky unit tests: tests/unittests/flows/llm_flows/test_functions_simple.py
original tests assert too strict time boundary, now we only assert the parallel execution time should be less than sequential execution time

PiperOrigin-RevId: 800563929
2025-08-28 12:17:03 -07:00
Xiang (Sean) Zhou 8d6f138fbe chore: Update oauth calendar sample agent to test the case when a subsequent tool call happends right after a tool call that requires auth
context: this is for reproducing https://github.com/google/adk-python/issues/1944 and verify corresponding fix
PiperOrigin-RevId: 800561025
2025-08-28 12:10:43 -07:00
Xiang (Sean) Zhou 3b922a2f6d fix: Only process the auth responses in the last event with content (if applicable i.e. it's authored by user)
fixes : https://github.com/google/adk-python/issues/1944
PiperOrigin-RevId: 800560805
2025-08-28 12:09:21 -07:00
Google Team Member 7975e8e196 refactor: Extract a utility for aggregating partial streaming responses and emitting LlmResponses for them as needed
PiperOrigin-RevId: 800521404
2025-08-28 10:29:14 -07:00
Wei Sun (Jack) 3bc2d77b4d chore(config): Reimplements AgentConfig with pydantic v2 convention and allow all possible values for agent_class field in all Agent Configs
All below are valid values now.

```
agent_class: LlmAgent
agent_class: google.adk.agents.LlmAgent
agent_class: google.adk.agents.llm_agent.LlmAgent
```
PiperOrigin-RevId: 800228114
2025-08-27 17:07:53 -07:00
Yifan Wang f743c29d00 chore: Bump version number to 1.13.0
PiperOrigin-RevId: 800210332
2025-08-27 16:09:42 -07:00
338 changed files with 38273 additions and 3316 deletions
+5 -3
View File
@@ -14,11 +14,12 @@ assignees: ''
A clear and concise description of what the bug is.
**To Reproduce**
Please share a minimal code and data to reproduce your problem.
Steps to reproduce the behavior:
1. Install '...'
2. Run '....'
3. Open '....'
4. See error
4. Provie error or stacktrace
**Expected behavior**
A clear and concise description of what you expected to happen.
@@ -27,12 +28,13 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- OS: [e.g. macOS, Linux, Windows]
- Python version(python -V):
- ADK version(pip show google-adk):
**Model Information:**
For example, which model is being used.
- Are you using LiteLLM: Yes/No
- Which model is being used(e.g. gemini-2.5-pro)
**Additional context**
Add any other context about the problem here.
@@ -0,0 +1,47 @@
name: Analyze New Release for ADK Docs Updates
on:
# Runs on every new release.
release:
types: [published]
# Manual trigger for testing and retrying.
workflow_dispatch:
jobs:
analyze-new-release-for-adk-docs-updates:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Load adk-bot SSH Private Key
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.ADK_BOT_SSH_PRIVATE_KEY }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests google-adk
- name: Run Analyzing Script
env:
GITHUB_TOKEN: ${{ secrets.ADK_TRIAGE_AGENT }}
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
GOOGLE_GENAI_USE_VERTEXAI: 0
DOC_OWNER: 'google'
CODE_OWNER: 'google'
DOC_REPO: 'adk-docs'
CODE_REPO: 'adk-python'
INTERACTIVE: 0
PYTHONPATH: contributing/samples/adk_documentation
run: python -m adk_release_analyzer.main
+11 -3
View File
@@ -3,10 +3,14 @@ name: ADK Answering Agent for Discussions
on:
discussion:
types: [created]
discussion_comment:
types: [created]
jobs:
agent-answer-questions:
if: github.event.discussion.category.name == 'Q&A'
if: >-
(github.event_name == 'discussion' && github.event.discussion.category.name == 'Q&A') ||
(github.event_name == 'discussion_comment' && contains(github.event.comment.body, '@adk-bot') && github.event.sender.login != 'adk-bot')
runs-on: ubuntu-latest
steps:
@@ -41,6 +45,10 @@ jobs:
OWNER: 'google'
REPO: 'adk-python'
INTERACTIVE: 0
DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
PYTHONPATH: contributing/samples
run: python -m adk_answering_agent.main
run: |
# Write discussion data to temporary file to avoid secret masking issues
cat > /tmp/discussion.json << 'EOF'
${{ toJson(github.event.discussion) }}
EOF
python -m adk_answering_agent.main --discussion-file /tmp/discussion.json
+1
View File
@@ -6,6 +6,7 @@ on:
jobs:
agent-triage-pull-request:
if: "!contains(github.event.pull_request.labels.*.name, 'bot triaged') && !contains(github.event.pull_request.labels.*.name, 'google-contributor')"
runs-on: ubuntu-latest
permissions:
pull-requests: write
+2
View File
@@ -17,6 +17,8 @@ Please refer to [ADK Project Overview and Architecture](https://github.com/googl
- ADK live related configs are in [run_config.py](https://github.com/google/adk-python/blob/main/src/google/adk/agents/run_config.py).
- ADK live under multi-agent scenario: we convert the audio into text. This text will be passed to next agent as context.
- Most logics are in [base_llm_flow.py](https://github.com/google/adk-python/blob/main/src/google/adk/flows/llm_flows/base_llm_flow.py) and [gemini_llm_connection.py](https://github.com/google/adk-python/blob/main/src/google/adk/models/gemini_llm_connection.py).
- Input transcription and output transcription should be added to session as Event.
- User audio or model audio should be saved into artifacts with a reference in Event to it.
- Tests are in [tests/unittests/streaming](https://github.com/google/adk-python/tree/main/tests/unittests/streaming).
## ADK: Style Guides
+168
View File
@@ -1,5 +1,173 @@
# Changelog
## [1.15.0](https://github.com/google/adk-python/compare/v1.14.1...v1.15.0) (2025-09-24)
### Features
* [Core]
* Adding the ContextFilterPlugin ([a06bf27](https://github.com/google/adk-python/commit/a06bf278cbc89f521c187ed51b032d82ffdafe2d))
* Adds plugin to save artifacts for issue [#2176](https://github.com/google/adk-python/issues/2176) ([657369c](https://github.com/google/adk-python/commit/657369cffe142ef3745cd5950d0d24a49f42f7fd))
* Expose log probs of candidates in LlmResponse ([f7bd3c1](https://github.com/google/adk-python/commit/f7bd3c111c211e880d7c1954dd4508b952704c68))
* [Context Caching]
* Support context caching ([c66245a](https://github.com/google/adk-python/commit/c66245a3b80192c16cb67ee3194f82c9a7c901e5))
- Support explicit context caching auto creation and lifecycle management.
Usage: `App(root_agent=..., plugins=..., context_cache_config=...)`
* Support non-text content in static instruction ([61213ce](https://github.com/google/adk-python/commit/61213ce4d4c10f7ecaf6ddb521672059cee27942))
* Support static instructions ([9be9cc2](https://github.com/google/adk-python/commit/9be9cc2feee92241fd2fbf9dea3a42de5a78e9ce))
- Support static instruction that won't change, put at the beginning of
the instruction.
Static instruction support inline_data and file_data as contents.
Dynamic instruction moved to the end of LlmRequest, increasing prefix
caching matching size.
Usage:
`LlmAgent(model=...,static_instruction =types.Content(parts=...), ... )`
* [Telemetry]
* Add --otel_to_cloud experimental support ([1ae0b82](https://github.com/google/adk-python/commit/1ae0b82f5602a57ad1ca975ca0b7c85003d1a28a), [b131268](https://github.com/google/adk-python/commit/b1312680f4ea9f21c3246a1d24392619643d71f5), [7870480](https://github.com/google/adk-python/commit/7870480c63bb4fc08cfb3cabc0e1f0458f0e85bd))
* Add GenAI Instrumentation if --otel_to_cloud is enabled ([cee365a](https://github.com/google/adk-python/commit/cee365a13d0d1b1f2be046c1cc29e24a8d1fdbcc))
* Support standard OTel env variables for exporter endpoints ([f157b2e](https://github.com/google/adk-python/commit/f157b2ee4caf4055e78f4657254e45913895f5de))
* Temporarily disable Cloud Monitoring integration in --otel_to_cloud ([3b80337](https://github.com/google/adk-python/commit/3b80337faf427460e4743e25dbb92578f823513f))
* [Services]
* Add endpoint to generate memory from session ([2595824](https://github.com/google/adk-python/commit/25958242db890b4d2aac8612f7f7cfbb561727fa))
* [Tools]
* Add Google Maps Grounding Tool to ADK ([6b49391](https://github.com/google/adk-python/commit/6b493915469ecb42068e24818ab547b0856e4709))
* **MCP:** Initialize tool_name_prefix in MCPToolse ([86dea5b](https://github.com/google/adk-python/commit/86dea5b53ac305367283b7e353b60d0f4515be3b))
* [Evals]
* Data model for storing App Details and data model for steps ([01923a9](https://github.com/google/adk-python/commit/01923a9227895906ca8ae32712d65b178e2cd7d5))
* Adds Rubric based final response evaluator ([5a485b0](https://github.com/google/adk-python/commit/5a485b01cd64cb49735e13ebd5e7fa3da02cd85f))
* Populate AppDetails to each Invocation ([d486795](https://github.com/google/adk-python/commit/d48679582de91050ca9c5106402319be9a8ae7e8))
* [Samples]
* Make the bigquery sample agent run with ADC out-of-the-box ([10cf377](https://github.com/google/adk-python/commit/10cf37749417856e394e62896231e41b13420f18))
### Bug Fixes
* Close runners after running eval ([86ee6e3](https://github.com/google/adk-python/commit/86ee6e3fa3690148d60358fc3dacb0e0ab40942b))
* Filter out thought parts when saving agent output to state ([632bf8b](https://github.com/google/adk-python/commit/632bf8b0bcf18ff4e4505e4e5f4c626510f366a2))
* Ignore empty function chunk in LiteLlm streaming response ([8a92fd1](https://github.com/google/adk-python/commit/8a92fd18b600da596c22fd80c6148511a136dfd0))
* Introduces a `raw_mcp_tool` method in `McpTool` to provide direct access to the underlying MCP tool ([6158075](https://github.com/google/adk-python/commit/6158075a657f8fe0835679e509face6191905403))
* Make a copy of the `columns` instead of modifying it in place ([aef1ee9](https://github.com/google/adk-python/commit/aef1ee97a55a310f3959d475b8d7d6bc3915ae48))
* Prevent escaping of Latin characters in LLM response ([c9ea80a](https://github.com/google/adk-python/commit/c9ea80af28e586c9cc1f643b365cdba82f80c700))
* Retain the consumers and transport registry when recreating the ClientFactory in remote_a2a_agent.py ([6bd33e1](https://github.com/google/adk-python/commit/6bd33e1be36f741a6ed0514197550f9f336262ed))
* Remove unsupported 'type': 'unknown' in test_common.py for fastapi 0.117.1 ([3745221](https://github.com/google/adk-python/commit/374522197fa6843f786bfd12d17ce0fc20461dfd))
### Documentation
* Correct the documentation of `after_agent_callback` ([b9735b2](https://github.com/google/adk-python/commit/b9735b2193267645781b268231d63c23c6fec654))
## [1.14.1](https://github.com/google/adk-python/compare/v1.14.0...v1.14.1) (2025-09-12)
### Bug Fixes
* Fix logging issues with RemoteA2aAgent [0c1f1fa](https://github.com/google/adk-python/commit/0c1f1fadeb5a6357af9cad0eff5d5e7103fc88b0)
## [1.14.0](https://github.com/google/adk-python/compare/v1.13.0...v1.14.0) (2025-09-10)
### Features
* [A2A]
* Allow users to pass their own agent card to to_a2a method [a1679da](https://github.com/google/adk-python/commit/a1679dae3fef70f1231afba3e97d45b59c314ae3)
* Allow custom part converters in A2A classes [b05fef9](https://github.com/google/adk-python/commit/b05fef9ba71f95ab2658eb4eb5608c141d49f82f)
* [Tools]
* Allow setting agent/application name and compute project for BigQuery tools [11a2ffe](https://github.com/google/adk-python/commit/11a2ffe35adbae977b49ceccf0e76e20c6dc90b6)
* Add BigQuery forecast tool [0935a40](https://github.com/google/adk-python/commit/0935a40011a3276ee7f7fa3b91678b4d63f22ba5)
* Add GkeCodeExecutor for sandboxed code execution on GKE [72ff9c6](https://github.com/google/adk-python/commit/72ff9c64a291aebb50b07446378f375e58882c4e)
* Add a tool confirmation flow that can guard tool execution with explicit confirmation and custom input [a17bcbb](https://github.com/google/adk-python/commit/a17bcbb2aa0f5c6aca460db96ed1cb7dd86fef84)
* Add audience and prompt as configurable for OAuth flows [edda922](https://github.com/google/adk-python/commit/edda922791f15ac37830ed95ebf76b9f836d9db4)
* Allow user specify embedding model for file retrieval [67f23df](https://github.com/google/adk-python/commit/67f23df25ad47aff3cb36d0fc9ce2c9b97bde09b)
* [Core]
* Allow all possible values for `agent_class` field in all Agent Configs [3bc2d77](https://github.com/google/adk-python/commit/3bc2d77b4d180e9c42b30d4d1ce580aa75abe501)
* Allow agent loader to load built-in agents from special directories in adk folder [578fad7](https://github.com/google/adk-python/commit/578fad7034a7b369a490ad0afa4dd2820463c22d)
* Upgrade ADK runner to use App in addition to root_agent [4df79dd](https://github.com/google/adk-python/commit/4df79dd5c92d96096d031b26470458d0bca79a79)
* Allow inject artifact into instructions [bb4cfde](https://github.com/google/adk-python/commit/bb4cfdec12370955d4038d6d8c86e04691f2308e)
* [Misc] Create an initial ADK release analyzer agent to find the doc updates needed between releases [e3422c6](https://github.com/google/adk-python/commit/e3422c616d18ec3850454ee83f2ef286198543ec)
### Bug Fixes
* Add a NOTE to agent transfer instructions listing available agents [43eec82](https://github.com/google/adk-python/commit/43eec82f8444c19455089655ee288200ec966577)
* Fix pagination of list_sessions in VertexAiSessionService [e63fe0c](https://github.com/google/adk-python/commit/e63fe0c0eb73ac6e22d975387dd2df3d2ba3f521)
* Fix AttributeError and indentation in parameter processing of LiteLlm [1e23652](https://github.com/google/adk-python/commit/1e23652968164c5fdfa5564e966e78799237d94b)
* Allow AgentTool to inherit/use plugins from its invocation context when running [1979dcf](https://github.com/google/adk-python/commit/1979dcf496be3fb75fa2063fc96f480bedeb5de2)
* Enforce foreign key constraint for SQLite DB [0c87907](https://github.com/google/adk-python/commit/0c87907bcb2e5687a4ad08bab450fc888a5b5233)
* Add back installing requirements.txt to Dockerfile template for cloud run [8e43f0d](https://github.com/google/adk-python/commit/8e43f0dd8321ea31d6ad970ad4402feb48cdbd3d)
* Only process the auth responses in the last event with content (if applicable i.e. it's authored by user) [3b922a2](https://github.com/google/adk-python/commit/3b922a2f6da373b0de78b022db5d5bcb5453379f)
* Extract a utility for aggregating partial streaming responses and emitting LlmResponses for them as needed [7975e8e](https://github.com/google/adk-python/commit/7975e8e1961c8e375e2af3506ea546580ff7e45d)
* Support saving text artifacts in GCS artifact service [cecf7e8](https://github.com/google/adk-python/commit/cecf7e805d19d20e940319a6e16bfc9015ead202)
* Fixes `thought` handling in contents.py and refactors its unit tests [a30851e](https://github.com/google/adk-python/commit/a30851ee16114103dca7b9736e79cb31e82ee4d8)
* Fixes the `thought` field handling in _planning.py [fe8b37b](https://github.com/google/adk-python/commit/fe8b37b0d3046a9c0dd90e8ddca2940c28d1a93f)
* Pass state_delta to runner in /run endpoint [a3410fa](https://github.com/google/adk-python/commit/a3410fab7b25cc0e9c5908e23a087b501466df76)
* Fix discussion answering github action workflow to escape the quote in the discussion content JSON [43c9681](https://github.com/google/adk-python/commit/43c96811da891a5b0c9cf1be525665e65f346a13)
* Send full MIME types for image/video/pdf in get_content [e45c3be](https://github.com/google/adk-python/commit/e45c3be23895b5ec68908ad9ee19bd622dcbd003)
* Fix flaky unit tests: tests/unittests/flows/llm_flows/test_functions_simple.py [b92b288](https://github.com/google/adk-python/commit/b92b288c978a9b3d1a76c8bcb96cc8f439ce610b)
* Make UT of a2a consistent about how tests should be skipped when python verison < 3.10 [98b0426](https://github.com/google/adk-python/commit/98b0426cd2dc5e28014ead22b22dbf50d42d0a9a)
### Improvements
* Update contribution guide [8174a29](https://github.com/google/adk-python/commit/8174a29c6db9fd22a5a563f3088bd538b90e9a50)
* Skip PR triage for already triaged or Google-contributor PRs [78eea1a](https://github.com/google/adk-python/commit/78eea1aa550790097a1005237acaec56309cd61e)
* Avoid mutable default arguments in `local_eval_service` and `runners` [64f11a6](https://github.com/google/adk-python/commit/64f11a6a67e7042768270c5587e87528c358bd06)
* Avoid mutable default arguments in `local_eval_service` and `runners` [5b465fd](https://github.com/google/adk-python/commit/5b465fd71b601a2a1ab95a74f7c9ddafe09085e5)
* Reorder dependencies in `pyproject.toml` [ca5f7f1](https://github.com/google/adk-python/commit/ca5f7f1ff0afb2b3c2457fb9efdf029dcf7494b7)
* Follow pydantic convention to make field_validator a public method [1448406](https://github.com/google/adk-python/commit/14484065c64396cebc4a1dde84d6b8b51439b990)
* Update comment to clarify `after_run` callbacks [7720616](https://github.com/google/adk-python/commit/7720616c5f1dc302f019c348a6dfa70d1cf0b135)
* Tune instructions to not ask root directory if it's already provided in the context [25df6c2](https://github.com/google/adk-python/commit/25df6c22d5942ead3a329f90ed2c10b374051ae6)
* Load discussion data from event content to avoid additional GraphQL API call [a503a0c](https://github.com/google/adk-python/commit/a503a0c807e50ec9dde7d5095f8e020861d1375d)
* Refactor discussion answering agent to merge answer_discussions.py into main.py [408d3df](https://github.com/google/adk-python/commit/408d3dfeb1475da343a15ae13e9b128985460a5d)
* Add community repo dependency group to pyproject toml [7b077ac](https://github.com/google/adk-python/commit/7b077ac3517f2b88d1bc4b732815ca766c791168)
* Add warning for using Gemini models via LiteLLM [9291daa](https://github.com/google/adk-python/commit/9291daaa8e399ca052f5a52dbb600d719dcc9fa8)
### Documentation
* Update root_agent description for clarity [467df1a](https://github.com/google/adk-python/commit/467df1a36f3ded1a0e324defcd94c557871c9190)
* Update the ask_data_insights docstring [aad1533](https://github.com/google/adk-python/commit/aad153322e54cc39c97e3e0bc71cbed72bcab477)
* Add contributing Spanner tools RAG agent sample [fcd748e](https://github.com/google/adk-python/commit/fcd748e17f4e0e7a3146716816c579f2ee973e6b)
### Tests
* Add functional telemetry tests [bc6b546](https://github.com/google/adk-python/commit/bc6b5462a76ee1cd718c75360daac94373d7c071)
* Add unit tests for the `App` class and improve `Runner` initialization tests [fc90ce9](https://github.com/google/adk-python/commit/fc90ce968f114f84b14829f8117797a4c256d710)
### Chores
* Use lazy % formatting in logging functions to fix pylint warnings [b431072](https://github.com/google/adk-python/commit/b4310727d90421a81a8afc47e3c344646ee7aee8)
* Update release cadence in README [decc19b](https://github.com/google/adk-python/commit/decc19b188fbf097995824f9ad7b7be1263b6338)
* Add `custom_metadata` to DatabaseSessionService [fb009d8](https://github.com/google/adk-python/commit/fb009d8ea672bbbef4753e4cd25229dbebd0ff8d)
* Update create_session endpoint to use Request message as post body [219815d](https://github.com/google/adk-python/commit/219815d2d7f45ac0cff28265f23fbf4f4e77163f)
## 1.13.0 (2025-08-27)
### Features
* [Tools] Add the ask_data_insights tool for natural language queries on BigQuery data [47b88d2](https://github.com/google/adk-python/commit/47b88d2b06d247a698915ebf74564dbb5d81153e)
### Bug Fixes
* Add the missing `from_config` class method in BaseToolset [2dd432c](https://github.com/google/adk-python/commit/2dd432cc1fe265a79986a28e2afb59ee2c83abb3)
* Change LlmResponse to use Content for transcriptions [3b997a0](https://github.com/google/adk-python/commit/3b997a0a07d1a2915bc64d64355f4dbabb7e0ba0)
* AgentTool returns last content, instead of the content in the last event [bcf0dda](https://github.com/google/adk-python/commit/bcf0dda8bcc221974098f3077007c9e84c63021a)
* Fix adk deploy docker file permission [ad81aa5](https://github.com/google/adk-python/commit/ad81aa54de1f38df580915b7f47834ea8e5f1004)
* Updating BaseAgent.clone() and LlmAgent.clone() to properly clone fields that are lists [29bb75f](https://github.com/google/adk-python/commit/29bb75f975fe0c9c9d9a7e534a9c20158e1cbe1e)
* Make tool description for bigquery `execute_sql` for various write modes self contained [167182b](https://github.com/google/adk-python/commit/167182be0163117f814c70f453d5b2e19bf474df)
* Set invocation_id and branch for event generated when both output_schema and tools are used [3f3aa7b](https://github.com/google/adk-python/commit/3f3aa7b32d63cae5750d71bc586c088427c979ea)
* Rework parallel_agent.py to always aclose async generators [826f554](https://github.com/google/adk-python/commit/826f5547890dc02e707be33a3d6a58b527dac223)
* Add table metadata info into Spanner tool `get_table_schema` and fix the key usage info [81a53b5](https://github.com/google/adk-python/commit/81a53b53d6336011187a50ae8f1544de9b2764a8)
* Fix Spanner DatabaseSessionService support [54ed079](https://github.com/google/adk-python/commit/54ed0791005350542708eb2c38f32ce8b92356bc)
* Add support for required params [c144b53](https://github.com/google/adk-python/commit/c144b5347cc459496d4fd41e0c63715ffffb4952)
* Replaced hard coded value for user_id to the value from the tool context from parent agent. [0b89f18](https://github.com/google/adk-python/commit/0b89f1882dccc1acd0ee109832053edecec04850)
### Improvements
* Allow user to specify protocol for A2A RPC URL in to_a2a utility [157f731](https://github.com/google/adk-python/commit/157f73181d123b0fddc34205dc74434fcbc43b2a)
* Passthrough extra args for `adk deploy cloud_run` as Cloud Run args [6806dea](https://github.com/google/adk-python/commit/6806deaf8811eb7f02ed958648886323aba16adb)
* Renames MCPTool and MCPToolset to McpTool and McpToolset [4c70606](https://github.com/google/adk-python/commit/4c7060612967253dae824a14c5c3f853a547469b)
* Ignore hidden files in autoformat.sh [0eb65c0](https://github.com/google/adk-python/commit/0eb65c07d52f71cf555f0c32dc34b2e4ac8cf2a2)
### Documentation
* Clean up docs in sample [a360bc2](https://github.com/google/adk-python/commit/a360bc25429bf4bef6a80da59afe30d6933a844b)
* Fixes root_agent.yaml in tool_mcp_stdio_notion_config for Agent Config sample and add README.md [2c088ac](https://github.com/google/adk-python/commit/2c088acc9b34f030537b02b45a4afd458445d15b)
* Add What's new section to README.md [ccab076](https://github.com/google/adk-python/commit/ccab076aceff917591eb3a3cc89a9f85226b832a)
## 1.12.0 (2025-08-21)
### Features
+98 -76
View File
@@ -2,25 +2,24 @@
We'd love to accept your patches and contributions to this project.
- [How to contribute](#how-to-contribute)
- [Before you begin](#before-you-begin)
- [Sign our Contributor License Agreement](#sign-our-contributor-license-agreement)
- [Review our community guidelines](#review-our-community-guidelines)
- [Contribution workflow](#contribution-workflow)
- [Finding Issues to Work On](#finding-issues-to-work-on)
- [Requirement for PRs](#requirement-for-prs)
- [Large or Complex Changes](#large-or-complex-changes)
- [Testing Requirements](#testing-requirements)
- [Unit Tests](#unit-tests)
- [Manual End-to-End (E2E) Tests](#manual-end-to-end-e2e-tests)
- [Documentation](#documentation)
- [Development Setup](#development-setup)
- [Code reviews](#code-reviews)
- [How to contribute](#how-to-contribute)
- [Before you begin](#before-you-begin)
- [Sign our Contributor License Agreement](#sign-our-contributor-license-agreement)
- [Review our community guidelines](#review-our-community-guidelines)
- [Contribution workflow](#contribution-workflow)
- [Finding Issues to Work On](#finding-issues-to-work-on)
- [Requirement for PRs](#requirement-for-prs)
- [Large or Complex Changes](#large-or-complex-changes)
- [Testing Requirements](#testing-requirements)
- [Unit Tests](#unit-tests)
- [Manual End-to-End (E2E) Tests](#manual-end-to-end-e2e-tests)
- [Documentation](#documentation)
- [Development Setup](#development-setup)
- [Code reviews](#code-reviews)
## Before you begin
# Before you begin
## Sign our Contributor License Agreement
### Sign our Contributor License Agreement
Contributions to this project must be accompanied by a
[Contributor License Agreement](https://cla.developers.google.com/about) (CLA).
@@ -34,73 +33,102 @@ was for a different project), you probably don't need to do it again.
Visit <https://cla.developers.google.com/> to see your current agreements or to
sign a new one.
## Review our community guidelines
### Review our community guidelines
This project follows
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).
# Contribution workflow
### Code reviews
## Finding Issues to Work On
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
- Browse issues labeled **`good first issue`** (newcomer-friendly) or **`help wanted`** (general contributions).
- For other issues, please kindly ask before contributing to avoid duplication.
## Contribution workflow
### Finding Issues to Work On
## Requirement for PRs
- Browse issues labeled **`good first issue`** (newcomer-friendly) or **`help
wanted`** (general contributions).
- For other issues, please kindly ask before contributing to avoid
duplication.
- All PRs, other than small documentation or typo fixes, should have a Issue associated. If not, please create one.
- Small, focused PRs. Keep changes minimal—one concern per PR.
- For bug fixes or features, please provide logs or screenshot after the fix is applied to help reviewers better understand the fix.
- Please include a `testing plan` section in your PR to talk about how you will test. This will save time for PR review. See `Testing Requirements` section for more details.
### Requirement for PRs
- All PRs, other than small documentation or typo fixes, should have a Issue
associated. If not, please create one.
- Small, focused PRs. Keep changes minimal—one concern per PR.
- For bug fixes or features, please provide logs or screenshot after the fix
is applied to help reviewers better understand the fix.
- Please include a `testing plan` section in your PR to talk about how you
will test. This will save time for PR review. See `Testing Requirements`
section for more details.
### Large or Complex Changes
## Large or Complex Changes
For substantial features or architectural revisions:
- Open an Issue First: Outline your proposal, including design considerations and impact.
- Gather Feedback: Discuss with maintainers and the community to ensure alignment and avoid duplicate work
- Open an Issue First: Outline your proposal, including design considerations
and impact.
- Gather Feedback: Discuss with maintainers and the community to ensure
alignment and avoid duplicate work
## Testing Requirements
### Testing Requirements
To maintain code quality and prevent regressions, all code changes must include comprehensive tests and verifiable end-to-end (E2E) evidence.
To maintain code quality and prevent regressions, all code changes must include
comprehensive tests and verifiable end-to-end (E2E) evidence.
#### Unit Tests
### Unit Tests
Please add or update unit tests for your change. Please include a summary of passed `pytest` results.
Please add or update unit tests for your change. Please include a summary of
passed `pytest` results.
Requirements for unit tests:
- **Coverage:** Cover new features, edge cases, error conditions, and typical use cases.
- **Location:** Add or update tests under `tests/unittests/`, following existing naming conventions (e.g., `test_<module>_<feature>.py`).
- **Framework:** Use `pytest`. Tests should be:
- Fast and isolated.
- Written clearly with descriptive names.
- Free of external dependencies (use mocks or fixtures as needed).
- **Quality:** Aim for high readability and maintainability; include docstrings or comments for complex scenarios.
- **Coverage:** Cover new features, edge cases, error conditions, and typical
use cases.
- **Location:** Add or update tests under `tests/unittests/`, following
existing naming conventions (e.g., `test_<module>_<feature>.py`).
- **Framework:** Use `pytest`. Tests should be:
- Fast and isolated.
- Written clearly with descriptive names.
- Free of external dependencies (use mocks or fixtures as needed).
- **Quality:** Aim for high readability and maintainability; include
docstrings or comments for complex scenarios.
### Manual End-to-End (E2E) Tests
#### Manual End-to-End (E2E) Tests
Manual E2E tests ensure integrated flows work as intended. Your tests should cover all scenarios. Sometimes, it's also good to ensure relevant functionality is not impacted.
Manual E2E tests ensure integrated flows work as intended. Your tests should
cover all scenarios. Sometimes, it's also good to ensure relevant functionality
is not impacted.
Depending on your change:
- **ADK Web:**
- Use the `adk web` to verify functionality.
- Capture and attach relevant screenshots demonstrating the UI/UX changes or outputs.
- Label screenshots clearly in your PR description.
- **ADK Web:**
- **Runner:**
- Provide the testing setup. For example, the agent definition, and the runner setup.
- Execute the `runner` tool to reproduce workflows.
- Include the command used and console output showing test results.
- Highlight sections of the log that directly relate to your change.
- Use the `adk web` to verify functionality.
- Capture and attach relevant screenshots demonstrating the UI/UX changes
or outputs.
- Label screenshots clearly in your PR description.
## Documentation
- **Runner:**
For any changes that impact user-facing documentation (guides, API reference, tutorials), please open a PR in the [adk-docs](https://github.com/google/adk-docs) repository to update relevant part before or alongside your code PR.
- Provide the testing setup. For example, the agent definition, and the
runner setup.
- Execute the `runner` tool to reproduce workflows.
- Include the command used and console output showing test results.
- Highlight sections of the log that directly relate to your change.
### Documentation
For any changes that impact user-facing documentation (guides, API reference,
tutorials), please open a PR in the
[adk-docs](https://github.com/google/adk-docs) repository to update relevant
part before or alongside your code PR.
## Development Setup
1. **Clone the repository:**
```shell
@@ -110,11 +138,13 @@ For any changes that impact user-facing documentation (guides, API reference, tu
2. **Install uv:**
Check out [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/).
Check out
[uv installation guide](https://docs.astral.sh/uv/getting-started/installation/).
3. **Create and activate a virtual environment:**
**NOTE**: ADK supports Python 3.9+. Python 3.11 and above is strongly recommended.
**NOTE**: ADK supports Python 3.9+. Python 3.11 and above is strongly
recommended.
Create a workspace venv using uv.
@@ -128,10 +158,7 @@ For any changes that impact user-facing documentation (guides, API reference, tu
source .venv/bin/activate
```
**windows**
```shell
source .\.venv\Scripts\activate
```
**windows** `shell source .\.venv\Scripts\activate`
4. **Install dependencies:**
@@ -147,7 +174,7 @@ For any changes that impact user-facing documentation (guides, API reference, tu
pytest ./tests/unittests
```
NOTE: for accurate repro of test failure, only include `test`, `eval` and
NOTE: for accurate repro of test failure, only include `test`, `eval` and
`a2a` as extra dependencies.
```shell
@@ -164,14 +191,14 @@ For any changes that impact user-facing documentation (guides, API reference, tu
./autoformat.sh
```
7. **Build the wheel file:**
7. **Build the wheel file:**
```shell
uv build
```
8. **Test the locally built wheel file:**
Have a simple testing folder setup as mentioned in the
8. **Test the locally built wheel file:** Have a simple testing folder setup as
mentioned in the
[quickstart](https://google.github.io/adk-docs/get-started/quickstart/).
Then following below steps to test your changes:
@@ -200,16 +227,11 @@ For any changes that impact user-facing documentation (guides, API reference, tu
## Contributing Resources
[Contributing folder](https://github.com/google/adk-python/tree/main/contributing) has resources that is helpful for contributors.
[Contributing folder](https://github.com/google/adk-python/tree/main/contributing)
has resources that is helpful for contributors.
## Vibe Coding
## Code reviews
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
# Vibe Coding
If you want to contribute by leveraging viber coding, the AGENTS.md (https://github.com/google/adk-python/tree/main/AGENTS.md) could be used as context to your LLM.
If you want to contribute by leveraging viber coding, the AGENTS.md
(https://github.com/google/adk-python/tree/main/AGENTS.md) could be used as
context to your LLM.
+8 -6
View File
@@ -27,11 +27,13 @@ Agent Development Kit (ADK) is a flexible and modular framework for developing a
---
## ✨ What's new
## 🔥 What's new
- **Agent Config**: Build agents without code. Check out the
[Agent Config](https://google.github.io/adk-docs/agents/config/) feature.
- **Tool Confirmation**: A [tool confirmation flow(HITL)](https://google.github.io/adk-docs/tools/confirmation/) that can guard tool execution with explicit confirmation and custom input
## ✨ Key Features
- **Rich Tool Ecosystem**: Utilize pre-built tools, custom functions,
@@ -64,7 +66,7 @@ You can install the latest stable version of ADK using `pip`:
pip install google-adk
```
The release cadence is weekly.
The release cadence is roughly bi-weekly.
This version is recommended for most users as it represents the most recent official release.
@@ -94,7 +96,7 @@ from google.adk.tools import google_search
root_agent = Agent(
name="search_assistant",
model="gemini-2.0-flash", # Or your preferred Gemini model
model="gemini-2.5-flash", # Or your preferred Gemini model
instruction="You are a helpful assistant. Answer user questions using Google Search when needed.",
description="An assistant that can search the web.",
tools=[google_search]
@@ -109,13 +111,13 @@ Define a multi-agent system with coordinator agent, greeter agent, and task exec
from google.adk.agents import LlmAgent, BaseAgent
# Define individual agents
greeter = LlmAgent(name="greeter", model="gemini-2.0-flash", ...)
task_executor = LlmAgent(name="task_executor", model="gemini-2.0-flash", ...)
greeter = LlmAgent(name="greeter", model="gemini-2.5-flash", ...)
task_executor = LlmAgent(name="task_executor", model="gemini-2.5-flash", ...)
# Create parent agent and assign children via sub_agents
coordinator = LlmAgent(
name="Coordinator",
model="gemini-2.0-flash",
model="gemini-2.5-flash",
description="I coordinate greetings and tasks.",
sub_agents=[ # Assign sub_agents here
greeter,
@@ -0,0 +1,206 @@
# Agent Builder Assistant
An intelligent assistant for building ADK multi-agent systems using YAML configurations.
## Quick Start
### Using ADK Web Interface
```bash
# From the ADK project root
adk web src/google/adk/agent_builder_assistant
```
### Programmatic Usage
```python
# Create with defaults
agent = AgentBuilderAssistant.create_agent()
# Create with custom settings
agent = AgentBuilderAssistant.create_agent(
model="gemini-2.5-pro",
schema_mode="query",
working_directory="/path/to/project"
)
```
## Core Features
### 🎯 **Intelligent Agent Design**
- Analyzes requirements and suggests appropriate agent types
- Designs multi-agent architectures (Sequential, Parallel, Loop patterns)
- Provides high-level design confirmation before implementation
### 📝 **Advanced YAML Configuration**
- Generates AgentConfig schema-compliant YAML files
- Supports all agent types: LlmAgent, SequentialAgent, ParallelAgent, LoopAgent
- Built-in validation with detailed error reporting
### 🛠️ **Multi-File Management**
- **Read/Write Operations**: Batch processing of multiple files
- **File Type Separation**: YAML files use validation tools, Python files use generic tools
- **Backup & Recovery**: Automatic backups before overwriting existing files
### 🗂️ **Project Structure Analysis**
- Explores existing project structures
- Suggests conventional ADK file organization
- Provides path recommendations for new components
### đź§­ **Dynamic Path Resolution**
- **Session Binding**: Each chat session bound to one root directory
- **Working Directory**: Automatic detection and context provision
- **ADK Source Discovery**: Finds ADK installation dynamically (no hardcoded paths)
## Schema Modes
Choose between two schema handling approaches:
### Embedded Mode (Default)
```python
agent = AgentBuilderAssistant.create_agent(schema_mode="embedded")
```
- Full AgentConfig schema embedded in context
- Faster execution, higher token usage
- Best for comprehensive schema work
### Query Mode
```python
agent = AgentBuilderAssistant.create_agent(schema_mode="query")
```
- Dynamic schema queries via tools
- Lower initial token usage
- Best for targeted schema operations
## Example Interactions
### Create a new agent
```
Create an agent that can roll n-sided number and check whether the rolled number is prime.
```
### Add Capabilities to Existing Agent
```
Could you make the agent under `./config_based/roll_and_check` a multi agent system : root_agent only for request routing and two sub agents responsible for two functions respectively ?
```
### Project Structure Analysis
```
Please analyze my existing project structure at './config_based/roll_and_check' and suggest improvements for better organization.
```
## Tool Ecosystem
### Core File Operations
- **`read_config_files`** - Read multiple YAML configurations with analysis
- **`write_config_files`** - Write multiple YAML files with validation
- **`read_files`** - Read multiple files of any type
- **`write_files`** - Write multiple files with backup options
- **`delete_files`** - Delete multiple files with backup options
### Project Analysis
- **`explore_project`** - Analyze project structure and suggest paths
- **`resolve_root_directory`** - Resolve paths with working directory context
### ADK knowledge Context
- **`google_search`** - Search for ADK examples and documentation
- **`url_context`** - Fetch content from URLs (GitHub, docs, etc.)
- **`search_adk_source`** - Search ADK source code with regex patterns
## File Organization Conventions
### ADK Project Structure
```
my_adk_project/
└── src/
└── my_app/
├── root_agent.yaml
├── sub_agent_1.yaml
├── sub_agent_2.yaml
├── tools/
│ ├── process_email.py # No _tool suffix
│ └── analyze_sentiment.py
└── callbacks/
├── logging.py # No _callback suffix
└── security.py
```
### Naming Conventions
- **Agent directories**: `snake_case`
- **Tool files**: `descriptive_action.py`
- **Callback files**: `descriptive_name.py`
- **Tool paths**: `project_name.tools.module.function_name`
- **Callback paths**: `project_name.callbacks.module.function_name`
## Session Management
### Root Directory Binding
Each chat session is bound to a single root directory:
- **Automatic Detection**: Working directory provided to model automatically
- **Session State**: Tracks established root directory across conversations
- **Path Resolution**: All relative paths resolved against session root
- **Directory Switching**: Suggest user starting new session to work in different directory
### Working Directory Context
```python
# The assistant automatically receives working directory context
agent = AgentBuilderAssistant.create_agent(
working_directory="/path/to/project"
)
# Model instructions include: "Working Directory: /path/to/project"
```
## Advanced Features
### Dynamic ADK Source Discovery
No hardcoded paths - works in any ADK installation:
```python
from google.adk.agent_builder_assistant.utils import (
find_adk_source_folder,
get_adk_schema_path,
load_agent_config_schema
)
# Find ADK source dynamically
adk_path = find_adk_source_folder()
# Load schema with caching
schema = load_agent_config_schema()
```
### Schema Validation
All YAML files validated against AgentConfig schema:
- **Syntax Validation**: YAML parsing with detailed error locations
- **Schema Compliance**: Full AgentConfig.json validation
- **Best Practices**: ADK naming and structure conventions
- **Error Recovery**: Clear suggestions for fixing validation errors
## Performance Optimization
### Efficient Operations
- **Multi-file Processing**: Batch operations reduce overhead
- **Schema Caching**: Global cache prevents repeated file reads
- **Dynamic Discovery**: Efficient ADK source location caching
- **Session Context**: Persistent directory binding across conversations
### Memory Management
- **Lazy Loading**: Schema loaded only when needed
- **Cache Control**: Manual cache clearing for testing/development
- **Resource Cleanup**: Automatic cleanup of temporary files
## Error Handling
### Comprehensive Validation
- **Path Validation**: All paths validated before file operations
- **Schema Compliance**: AgentConfig validation with detailed error reporting
- **Python Syntax**: Syntax validation for generated Python code
- **Backup Creation**: Automatic backups before overwriting files
### Recovery Mechanisms
- **Retry Suggestions**: Clear guidance for fixing validation errors
- **Backup Restoration**: Easy recovery from automatic backups
- **Error Context**: Detailed error messages with file locations and suggestions
This comprehensive assistant provides everything needed for intelligent, efficient ADK agent system creation with proper validation, file management, and project organization.
@@ -0,0 +1,28 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Agent Builder Assistant for ADK.
This package provides an intelligent assistant for building multi-agent systems
using YAML configurations. It can be used directly as an agent or integrated
with ADK tools and web interfaces.
"""
from . import agent # Import to make agent.root_agent available
from .agent_builder_assistant import AgentBuilderAssistant
__all__ = [
'AgentBuilderAssistant',
'agent', # Make agent module available for adk web discovery
]
@@ -0,0 +1,21 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Agent Builder Assistant instance for ADK web testing."""
from .agent_builder_assistant import AgentBuilderAssistant
# Create the agent instance using the factory
# The root_agent variable is what ADK looks for when loading agents
root_agent = AgentBuilderAssistant.create_agent()
@@ -0,0 +1,256 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Agent factory for creating Agent Builder Assistant with embedded schema."""
from pathlib import Path
from typing import Callable
from typing import Optional
from typing import Union
from google.adk.agents import LlmAgent
from google.adk.agents.readonly_context import ReadonlyContext
from google.adk.models import BaseLlm
from google.adk.tools import AgentTool
from google.adk.tools import FunctionTool
from .sub_agents.google_search_agent import create_google_search_agent
from .sub_agents.url_context_agent import create_url_context_agent
from .tools.cleanup_unused_files import cleanup_unused_files
from .tools.delete_files import delete_files
from .tools.explore_project import explore_project
from .tools.read_config_files import read_config_files
from .tools.read_files import read_files
from .tools.resolve_root_directory import resolve_root_directory
from .tools.search_adk_source import search_adk_source
from .tools.write_config_files import write_config_files
from .tools.write_files import write_files
from .utils import load_agent_config_schema
class AgentBuilderAssistant:
"""Agent Builder Assistant factory for creating configured instances."""
@staticmethod
def create_agent(
model: Union[str, BaseLlm] = "gemini-2.5-flash",
working_directory: Optional[str] = None,
) -> LlmAgent:
"""Create Agent Builder Assistant with embedded ADK AgentConfig schema.
Args:
model: Model to use for the assistant (default: gemini-2.5-flash)
working_directory: Working directory for path resolution (default: current
working directory)
Returns:
Configured LlmAgent with embedded ADK AgentConfig schema
"""
# Load full ADK AgentConfig schema directly into instruction context
instruction = AgentBuilderAssistant._load_instruction_with_schema(
model, working_directory
)
# TOOL ARCHITECTURE: Hybrid approach using both AgentTools and FunctionTools
#
# Why use sub-agents for built-in tools?
# - ADK's built-in tools (google_search, url_context) are designed as agents
# - AgentTool wrapper allows integrating them into our agent's tool collection
# - Maintains compatibility with existing ADK tool ecosystem
# Built-in ADK tools wrapped as sub-agents
google_search_agent = create_google_search_agent()
url_context_agent = create_url_context_agent()
agent_tools = [AgentTool(google_search_agent), AgentTool(url_context_agent)]
# CUSTOM FUNCTION TOOLS: Agent Builder specific capabilities
#
# Why FunctionTool pattern?
# - Automatically generates tool declarations from function signatures
# - Cleaner than manually implementing BaseTool._get_declaration()
# - Type hints and docstrings become tool descriptions automatically
# Core agent building tools
custom_tools = [
FunctionTool(read_config_files), # Read/parse multiple YAML configs
FunctionTool(
write_config_files
), # Write/validate multiple YAML configs
FunctionTool(explore_project), # Analyze project structure
# Working directory context tools
FunctionTool(resolve_root_directory),
# File management tools (multi-file support)
FunctionTool(read_files), # Read multiple files
FunctionTool(write_files), # Write multiple files
FunctionTool(delete_files), # Delete multiple files
FunctionTool(cleanup_unused_files),
# ADK source code search (regex-based)
FunctionTool(search_adk_source), # Search ADK source with regex
]
# Combine all tools
all_tools = agent_tools + custom_tools
# Create agent directly using LlmAgent constructor
agent = LlmAgent(
name="agent_builder_assistant",
description=(
"Intelligent assistant for building ADK multi-agent systems "
"using YAML configurations"
),
instruction=instruction,
model=model,
tools=all_tools,
)
return agent
@staticmethod
def _load_schema() -> str:
"""Load ADK AgentConfig.json schema content and format for YAML embedding."""
# CENTRALIZED ADK AGENTCONFIG SCHEMA LOADING: Use common utility function
# This avoids duplication across multiple files and provides consistent
# ADK AgentConfig schema loading with caching and error handling.
schema_content = load_agent_config_schema(
raw_format=True, # Get as JSON string
escape_braces=True, # Escape braces for template embedding
)
# Format as indented code block for instruction embedding
#
# Why indentation is needed:
# - The ADK AgentConfig schema gets embedded into instruction templates using .format()
# - Proper indentation maintains readability in the final instruction
# - Code block markers (```) help LLMs recognize this as structured data
#
# Example final instruction format:
# "Here is the ADK AgentConfig schema:
# ```json
# {"type": "object", "properties": {...}}
# ```"
lines = schema_content.split("\n")
indented_lines = [" " + line for line in lines] # 2-space indent
return "```json\n" + "\n".join(indented_lines) + "\n ```"
@staticmethod
def _load_instruction_with_schema(
model: Union[str, BaseLlm],
working_directory: Optional[str] = None,
) -> Callable[[ReadonlyContext], str]:
"""Load instruction template and embed ADK AgentConfig schema content."""
instruction_template = (
AgentBuilderAssistant._load_embedded_schema_instruction_template()
)
schema_content = AgentBuilderAssistant._load_schema()
# Get model string for template replacement
model_str = (
str(model)
if isinstance(model, str)
else getattr(model, "model_name", str(model))
)
# Fill the instruction template with ADK AgentConfig schema content and default model
instruction_text = instruction_template.format(
schema_content=schema_content, default_model=model_str
)
# Return a function that accepts ReadonlyContext and returns the instruction
def instruction_provider(context: ReadonlyContext) -> str:
return AgentBuilderAssistant._compile_instruction_with_context(
instruction_text, context, working_directory
)
return instruction_provider
@staticmethod
def _load_embedded_schema_instruction_template() -> str:
"""Load instruction template for embedded ADK AgentConfig schema mode."""
template_path = Path(__file__).parent / "instruction_embedded.template"
if not template_path.exists():
raise FileNotFoundError(
f"Instruction template not found at {template_path}"
)
with open(template_path, "r", encoding="utf-8") as f:
return f.read()
@staticmethod
def _compile_instruction_with_context(
instruction_text: str,
context: ReadonlyContext,
working_directory: Optional[str] = None,
) -> str:
"""Compile instruction with session context and working directory information.
This method enhances instructions with:
1. Working directory information for path resolution
2. Session-based root directory binding if available
Args:
instruction_text: Base instruction text
context: ReadonlyContext from the agent session
working_directory: Optional working directory for path resolution
Returns:
Enhanced instruction text with context information
"""
import os
# Get working directory (use provided or current working directory)
actual_working_dir = working_directory or os.getcwd()
# Check for existing root directory in session state
session_root_directory = context._invocation_context.session.state.get(
"root_directory"
)
# Compile additional context information
context_info = f"""
## SESSION CONTEXT
**Working Directory**: `{actual_working_dir}`
- Use this as the base directory for path resolution when calling resolve_root_directory
- Pass this as the working_directory parameter to resolve_root_directory tool
"""
if session_root_directory:
context_info += f"""**Established Root Directory**: `{session_root_directory}`
- This session is bound to root directory: {session_root_directory}
- DO NOT ask the user for root directory - use this established path
- All agent building should happen within this root directory
- If user wants to work in a different directory, ask them to start a new chat session
"""
else:
context_info += f"""**Root Directory**: Not yet established
- You MUST ask the user for their desired root directory first
- Use resolve_root_directory tool to validate the path
- Once confirmed, this session will be bound to that root directory
"""
context_info += """**Session Binding Rules**:
- Each chat session is bound to ONE root directory
- Once established, work only within that root directory
- To switch directories, user must start a new chat session
- Always verify paths using resolve_root_directory tool before creating files
"""
return instruction_text + context_info
@@ -0,0 +1,350 @@
# Agent Builder Assistant - Embedded Schema Mode
You are an intelligent Agent Builder Assistant specialized in creating and configuring ADK (Agent Development Kit) multi-agent systems using YAML configuration files.
## Your Purpose
Help users design, build, and configure sophisticated multi-agent systems for the ADK framework. You guide users through the agent creation process by asking clarifying questions, suggesting optimal architectures, and generating properly formatted YAML configuration files that comply with the ADK AgentConfig schema.
## CRITICAL BEHAVIOR RULE
**NEVER assume users want to create agents unless they explicitly ask to CREATE, BUILD, GENERATE, IMPLEMENT, or UPDATE something.**
When users ask informational questions like "find me examples", "show me samples", "how do I", etc., they want INFORMATION ONLY. Provide the information and stop. Do not offer to create anything or ask for root directories.
## Core Capabilities
1. **Agent Architecture Design**: Analyze requirements and suggest appropriate agent types (LlmAgent, SequentialAgent, ParallelAgent, LoopAgent)
2. **YAML Configuration Generation**: Create proper ADK agent configuration files with correct ADK AgentConfig schema compliance
3. **Tool Integration**: Help configure and integrate various tool types (Function tools, Google API tools, MCP tools, etc.)
4. **Python File Management**: Create, update, and delete Python files for custom tools and callbacks per user request
5. **Project Structure**: Guide proper ADK project organization and file placement
6. **ADK Knowledge & Q&A**: Answer questions about ADK concepts, APIs, usage patterns, troubleshooting, and best practices using comprehensive research capabilities
## ADK AgentConfig Schema Reference
You have access to the complete ADK AgentConfig schema embedded in your context:
{schema_content}
Always reference this schema when creating configurations to ensure compliance.
## Workflow Guidelines
### 1. Discovery Phase
- **DETERMINE USER INTENT FIRST**:
* **INFORMATIONAL QUESTIONS** (Answer directly WITHOUT asking for root directory):
- "Could you find me examples of..." / "Find me samples of..."
- "Show me how to..." / "How do I..."
- "What is..." / "What are..." / "Explain..."
- "Can you show me..." / "Do you have examples of..."
- "I'm looking for information about..." / "I need to understand..."
- Questions about ADK capabilities, concepts, or existing implementations
- **CRITICAL**: For informational questions, provide the requested information and STOP. Do NOT offer to create, build, or generate anything unless explicitly asked.
* **CREATION/BUILDING INTENT** (Only then ask for root directory):
- "Create a new agent..." / "Build me an agent..."
- "Generate an agent..." / "Implement an agent..."
- "Update my agent..." / "Modify my agent..." / "Change my agent..."
- "I want to create..." / "Help me build..." / "Help me update..."
- "Set up a project..." / "Make me an agent..."
**EXAMPLE OF CORRECT BEHAVIOR:**
- User: "Could you find me a sample agent that can list my calendar events?"
- âś… CORRECT: Search for examples, show the samples found, explain how they work, and STOP.
- ❌ WRONG: "Before I proceed with creating an agent..." or asking for root directory.
- **ROOT DIRECTORY ESTABLISHMENT** (Only for Creation/Building):
* **FIRST**: Check SESSION CONTEXT section below for "Established Root Directory"
* **IF ESTABLISHED**: Use the existing session root directory - DO NOT ask again
* **IF NOT ESTABLISHED**: Ask user for root directory to establish working context
- **MODEL PREFERENCE**: Always ask for explicit model confirmation when LlmAgent(s) will be needed
* **When to ask**: After analyzing requirements and deciding that LlmAgent is needed for the solution
* **MANDATORY CONFIRMATION**: Say "Please confirm what model you want to use" - do NOT assume or suggest defaults
* **EXAMPLES**: "gemini-2.5-flash", "gemini-2.5-pro", etc.
* **RATIONALE**: Only LlmAgent requires model specification; workflow agents do not
* **DEFAULT ONLY**: Use "{default_model}" only if user explicitly says "use default" or similar
- **CRITICAL PATH RESOLUTION**: If user provides a relative path (e.g., `./config_agents/roll_and_check`):
* **FIRST**: Call `resolve_root_directory` to get the correct absolute path
* **VERIFY**: The resolved path matches user's intended location
* **EXAMPLE**: `./config_agents/roll_and_check` should resolve to `/Users/user/Projects/adk-python/config_agents/roll_and_check`, NOT `/config_agents/roll_and_check`
- Understand the user's goals and requirements through targeted questions
- Explore existing project structure using the RESOLVED ABSOLUTE PATH
- Identify integration needs (APIs, databases, external services)
### 2. Design Phase
- **MANDATORY HIGH-LEVEL DESIGN CONFIRMATION**: Present complete architecture design BEFORE any implementation
- **ASK FOR EXPLICIT CONFIRMATION**: "Does this design approach work for you? Should I proceed with implementation?"
- **INCLUDE IN DESIGN PRESENTATION**:
* Agent types and their roles
* Tool requirements and purposes
* File structure overview
* Model selection (if applicable)
- **WAIT FOR USER CONFIRMATION**: Do not proceed to implementation until user confirms the design
- **NO FILE CONTENT**: Do not show any file content during design phase - only architecture overview
### 3. Implementation Phase
**MANDATORY CONFIRMATION BEFORE ANY WRITES:**
- **NEVER write any file without explicit user confirmation**
- **Always present proposed changes first** and ask "Should I proceed with these changes?"
- **For modifications**: Show exactly what will be changed and ask for approval
- **For new files**: Show the complete content and ask for approval
- **For existing file modifications**: Ask "Should I create a backup before modifying this file?"
- **Use backup_existing parameter**: Set to True only if user explicitly requests backup
**IMPLEMENTATION ORDER (CRITICAL - ONLY AFTER USER CONFIRMS DESIGN):**
**STEP 1: YAML CONFIGURATION FILES FIRST**
1. Generate all YAML configuration files
2. Present complete YAML content to user for confirmation
3. Ask: "Should I create these YAML configuration files?"
4. Only proceed after user confirmation
**STEP 2: PYTHON FILES SECOND**
1. Generate Python tool/callback files
2. Present complete Python content to user for confirmation
3. Ask: "Should I create these Python files?"
4. Only proceed after user confirmation
1. **Present all proposed changes** - Show exact file contents and modifications
2. **Get explicit user approval** - Wait for "yes" or "proceed" before any writes
3. **Execute approved changes** - Only write files after user confirms
* ⚠️ **YAML files**: Use `write_config_files` (root_agent.yaml, etc.)
* ⚠️ **Python files**: Use `write_files` (tools/*.py, etc.)
4. **Clean up unused files** - Use cleanup_unused_files and delete_files to remove obsolete tool files
**YAML Configuration Requirements:**
- Main agent file MUST be named `root_agent.yaml`
- **Sub-agent placement**: Place ALL sub-agent YAML files in the root folder, NOT in `sub_agents/` subfolder
- Tool paths use format: `project_name.tools.module.function_name` (must start with project folder name, no `.py` extension, all dots)
* **Example**: For project at `config_agents/roll_and_check` with tool in `tools/is_prime.py`, use: `roll_and_check.tools.is_prime.is_prime`
* **Pattern**: `{{{{project_folder_name}}}}.tools.{{{{module_name}}}}.{{{{function_name}}}}`
* **CRITICAL**: Use only the final component of the root folder path as project_folder_name (e.g., for `./config_based/roll_and_check`, use `roll_and_check` not `config_based.roll_and_check`)
- No function declarations in YAML (handled automatically by ADK)
**TOOL IMPLEMENTATION STRATEGY:**
- **For simple/obvious tools**: Implement them directly with actual working code
* Example: dice rolling, prime checking, basic math, file operations
* Don't ask users to "fill in TODO comments" for obvious implementations
- **For complex/business-specific tools**: Generate proper function signatures with TODO comments
* Example: API integrations requiring API keys, complex business logic
- **Always generate correct function signatures**: If user wants `roll_dice` and `is_prime`, generate those exact functions, not generic `tool_name`
**CRITICAL: Tool Usage Patterns - MANDATORY FILE TYPE SEPARATION**
⚠️ **YAML FILES (.yaml, .yml) - MUST USE CONFIG TOOLS:**
- **ALWAYS use `write_config_files`** for writing YAML configuration files (root_agent.yaml, etc.)
- **ALWAYS use `read_config_files`** for reading YAML configuration files
- **NEVER use `write_files` for YAML files** - it lacks validation and schema compliance
⚠️ **PYTHON/OTHER FILES (.py, .txt, .md) - USE GENERAL FILE TOOLS:**
- **Use `write_files`** for Python tools, scripts, documentation, etc.
- **Use `read_files`** for non-YAML content
⚠️ **WHY THIS SEPARATION MATTERS:**
- `write_config_files` validates YAML syntax and ADK AgentConfig schema compliance
- `write_files` is raw file writing without validation
- Using wrong tool can create invalid configurations
- **For ADK code questions**: Use `search_adk_source` then `read_files` for complete context
- **File deletion**: Use `delete_files` for multiple file deletion with backup options
**TOOL GENERATION RULES:**
- **Match user requirements exactly**: Generate the specific functions requested
- **Use proper parameter types**: Don't use generic `parameter: str` when specific types are needed
- **Implement when possible**: Write actual working code for simple, well-defined functions
- **ONE TOOL PER FILE POLICY**: Always create separate files for individual tools
* **Example**: Create `roll_dice.py` and `is_prime.py` instead of `dice_tools.py`
* **Benefit**: Enables easy cleanup when tools are no longer needed
* **Exception**: Only use multi-tool files for legitimate toolsets with shared logic
### 4. Validation Phase
- Review generated configurations for schema compliance
- Test basic functionality when possible
- Provide clear next steps for the user
## Available Tools
### Core Agent Building Tools
#### Configuration Management (MANDATORY FOR .yaml/.yml FILES)
- **write_config_files**: ⚠️ REQUIRED for ALL YAML files (root_agent.yaml, sub-agents/*.yaml)
* Validates YAML syntax and ADK AgentConfig schema compliance
* Example: `write_config_files({{"./project/root_agent.yaml": yaml_content}})`
- **read_config_files**: Read and parse multiple YAML configuration files with validation and metadata extraction
- **config_file_reader**: Legacy function (use read_config_files instead)
- **config_file_writer**: Legacy function (use write_config_files instead)
#### File Management (Use for Python files and other content)
- **read_files**: Read content from multiple files (Python tools, scripts, documentation)
- **write_files**: Write content to multiple files (Python tools, callbacks, scripts)
- **delete_files**: Delete multiple files with optional backup creation
- **cleanup_unused_files**: Identify and clean up unused files
- **delete_file**: Legacy function (use delete_files instead)
#### Project Organization
- **explore_project**: Explore project structure and suggest conventional file paths
- **get_working_directory_info**: Get current working directory and execution context information
- **resolve_root_directory**: Resolve path issues when execution context differs from user's working directory
### ADK Knowledge and Research Tools
#### Web-based Research
- **google_search_agent**: Search web for ADK examples, patterns, and documentation (returns full page content as results)
- **url_context_agent**: Fetch content from specific URLs when mentioned in search results or user queries (use only when specific URLs need additional fetching)
#### Local ADK Source Search
- **search_adk_source**: Search ADK source code using regex patterns for precise code lookups
* Use for finding class definitions: `"class FunctionTool"`
* Use for constructor signatures: `"def __init__.*FunctionTool"`
* Use for method definitions: `"def method_name"`
* Returns matches with file paths, line numbers, and context
* Follow up with **read_files** to get complete file contents
**Research Workflow for ADK Questions:**
1. **search_adk_source** - Find specific code patterns with regex
2. **read_files** - Read complete source files for detailed analysis
3. **google_search_agent** - Find external examples and documentation
4. **url_context_agent** - Fetch specific GitHub files or documentation pages
### When to Use Research Tools
**ALWAYS use research tools when:**
1. **User asks ADK questions**: Any questions about ADK concepts, APIs, usage patterns, or troubleshooting
2. **Unfamiliar ADK features**: When user requests features you're not certain about
3. **Agent type clarification**: When unsure about agent types, their capabilities, or configuration
4. **Best practices**: When user asks for examples or best practices
5. **Error troubleshooting**: When helping debug ADK-related issues
6. **Agent building uncertainty**: When unsure how to create agents or what's the best practice
7. **Architecture decisions**: When evaluating different approaches or patterns for agent design
**Research Tool Usage Patterns:**
**For ADK Code Questions (NEW - Preferred Method):**
1. **search_adk_source** - Find exact code patterns:
* Class definitions: `"class FunctionTool"` or `"class.*Agent"`
* Constructor signatures: `"def __init__.*FunctionTool"`
* Method implementations: `"def get_declaration"`
* Import patterns: `"from.*tools"`
2. **read_files** - Get complete file context:
* Read full source files identified by search
* Understand complete implementation details
* Analyze class relationships and usage patterns
**For External Examples and Documentation:**
- **google_search_agent**: Search and analyze web content (returns full page content, not just URLs)
* Search within key repositories: "site:github.com/google/adk-python ADK SequentialAgent examples"
* Search documentation: "site:github.com/google/adk-docs agent configuration patterns"
* Search sample repository: "site:github.com/google/adk-samples multi-agent workflow"
* General searches: "ADK workflow patterns", "ADK tool integration patterns", "ADK project structure"
* Returns complete page content as search results - no need for additional URL fetching
- **url_context_agent**: Fetch specific URLs only when:
* Specific URLs are mentioned in search results that need additional content
* User provides specific URLs in their query
* You need to fetch content from URLs found within google_search results
* NOT needed for general searches - google_search_agent already provides page content
**Research for Agent Building:**
- When user requests complex multi-agent systems: Search for similar patterns in samples
- When unsure about tool integration: Look for tool usage examples in contributing/samples
- When designing workflows: Find SequentialAgent, ParallelAgent, or LoopAgent examples
- When user needs specific integrations: Search for API, database, or service integration examples
## Code Generation Guidelines
### When Creating Python Tools or Callbacks:
1. **Always search for current examples first**: Use google_search_agent to find "ADK tool_context examples" or "ADK callback_context examples"
2. **Reference contributing/samples**: Use url_context_agent to fetch specific examples from https://github.com/google/adk-python/tree/main/contributing/samples
3. **Look for similar patterns**: Search for tools or callbacks that match your use case
4. **Use snake_case**: Function names should be snake_case (e.g., `check_prime`, `roll_dice`)
5. **Remove tool suffix**: Don't add "_tool" to function names
6. **Implement simple functions**: For obvious functions like `is_prime`, `roll_dice`, replace TODO with actual implementation
7. **Keep TODO for complex**: For complex business logic, leave TODO comments
8. **Follow current ADK patterns**: Always search for and reference the latest examples from contributing/samples
## Important ADK Requirements
**File Naming & Structure:**
- Main configuration MUST be `root_agent.yaml` (not `agent.yaml`)
- Agent directories need `__init__.py` with `from . import agent`
- Python files in agent directory, YAML at root level
**Tool Configuration:**
- Function tools: `project_name.tools.module.function_name` format (all dots, must start with project folder name)
- No `.py` extension in tool paths
- No function declarations needed in YAML
- **Critical**: Tool paths must include the project folder name as the first component (final component of root folder path only)
**ADK Agent Types and Model Field Rules:**
- **LlmAgent**: REQUIRES `model` field - this agent directly uses LLM for responses
- **SequentialAgent**: NO `model` field - workflow agent that orchestrates other agents in sequence
- **ParallelAgent**: NO `model` field - workflow agent that runs multiple agents in parallel
- **LoopAgent**: NO `model` field - workflow agent that executes agents in a loop
- **CRITICAL**: Only LlmAgent accepts a model field. Workflow agents (Sequential/Parallel/Loop) do NOT have model fields
**ADK AgentConfig Schema Compliance:**
- Always reference the embedded ADK AgentConfig schema to verify field requirements
- **MODEL FIELD RULES**:
* **LlmAgent**: `model` field is REQUIRED - Ask user for preference only when LlmAgent is needed, use "{default_model}" if not specified
* **Workflow Agents**: `model` field is FORBIDDEN - Remove model field entirely for Sequential/Parallel/Loop agents
- Optional fields: description, instruction, tools, sub_agents as defined in ADK AgentConfig schema
## Critical Path Handling Rules
**NEVER assume relative path context** - Always resolve paths first!
### For relative paths provided by users:
1. **ALWAYS call `resolve_root_directory`** to convert relative to absolute path
2. **Verify the resolved path** matches user's intended location
3. **Use the resolved absolute path** for all file operations
### Examples:
- **User input**: `./config_agents/roll_and_check`
- **WRONG approach**: Create files at `/config_agents/roll_and_check`
- **CORRECT approach**:
1. Call `resolve_root_directory("./config_agents/roll_and_check")`
2. Get resolved path: `/Users/user/Projects/adk-python/config_agents/roll_and_check`
3. Use the resolved absolute path for all operations
## Success Criteria
### Design Phase Success:
1. Root folder path confirmed and analyzed with explore_project
2. Clear understanding of user requirements through targeted questions
3. Well-researched architecture based on proven ADK patterns
4. Comprehensive design proposal with agent relationships, tool mappings, AND specific file paths
5. User approval of both architecture and file structure before any implementation
### Implementation Phase Success:
1. Files created at exact paths specified in approved design
2. No redundant suggest_file_path calls for pre-approved paths
3. Generated configurations pass schema validation (automatically checked)
4. Follow ADK naming and organizational conventions
5. Be immediately testable with `adk run [root_directory]` or via `adk web` interface
6. Include clear, actionable instructions for each agent
7. Use appropriate tools for intended functionality
## Key Reminder
**Your primary role is to be a collaborative architecture consultant that follows an efficient, user-centric workflow:**
1. **Always ask for root folder first** - Know where to create the project
2. **Design with specific paths** - Include exact file locations in proposals
3. **Provide high-level architecture overview** - When confirming design, always include:
* Overall system architecture and component relationships
* Agent types and their responsibilities
* Tool integration patterns and data flow
* File structure with clear explanations of each component's purpose
4. **Get complete approval** - Architecture, design, AND file structure confirmed together
5. **Implement efficiently** - Use approved paths directly without redundant tool calls
6. **Focus on collaboration** - Ensure user gets exactly what they need with clear understanding
**This workflow eliminates inefficiencies and ensures users get well-organized, predictable file structures in their chosen location.**
## Running Generated Agents
**Correct ADK Commands:**
- `adk run [root_directory]` - Run agent from root directory (e.g., `adk run config_agents/roll_and_check`)
- `adk web [parent_directory]` - Start web interface, then select agent from dropdown menu (e.g., `adk web config_agents`)
**Incorrect Commands to Avoid:**
- `adk run [root_directory]/root_agent.yaml` - Do NOT specify the YAML file directly
- `adk web` without parent directory - Must specify the parent folder containing the agent projects
- Always use the project directory for `adk run`, and parent directory for `adk web`
@@ -0,0 +1,20 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Sub-agents for Agent Builder Assistant."""
from .google_search_agent import create_google_search_agent
from .url_context_agent import create_url_context_agent
__all__ = ['create_google_search_agent', 'create_url_context_agent']
@@ -0,0 +1,59 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Sub-agent for Google Search functionality."""
from google.adk.agents import LlmAgent
from google.adk.tools import google_search
def create_google_search_agent() -> LlmAgent:
"""Create a sub-agent that only uses google_search tool."""
return LlmAgent(
name="google_search_agent",
description=(
"Agent for performing Google searches to find ADK examples and"
" documentation"
),
instruction="""You are a specialized search agent for the Agent Builder Assistant.
Your role is to search for relevant ADK (Agent Development Kit) examples, patterns, documentation, and solutions.
When given a search query, use the google_search tool to find:
- ADK configuration examples and patterns
- Multi-agent system architectures and workflows
- Best practices and documentation
- Similar use cases and implementations
- Troubleshooting solutions and error fixes
- API references and implementation guides
SEARCH STRATEGIES:
- Use site-specific searches for targeted results:
* "site:github.com/google/adk-python [query]" for core ADK examples
* "site:github.com/google/adk-samples [query]" for sample implementations
* "site:github.com/google/adk-docs [query]" for documentation
- Use general searches for broader community solutions
- Search for specific agent types, tools, or error messages
- Look for configuration patterns and architectural approaches
Return the search results with:
1. Relevant URLs found
2. Brief description of what each result contains
3. Relevance to the original query
4. Suggestions for which URLs should be fetched for detailed analysis
Focus on finding practical, actionable examples that can guide ADK development and troubleshooting.""",
model="gemini-2.5-flash",
tools=[google_search],
)
@@ -0,0 +1,62 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Sub-agent for URL context fetching functionality."""
from google.adk.agents import LlmAgent
from google.adk.tools import url_context
def create_url_context_agent() -> LlmAgent:
"""Create a sub-agent that only uses url_context tool."""
return LlmAgent(
name="url_context_agent",
description=(
"Agent for fetching and analyzing content from URLs, especially"
" GitHub repositories and documentation"
),
instruction="""You are a specialized URL content analysis agent for the Agent Builder Assistant.
Your role is to fetch and analyze complete content from URLs to extract detailed, actionable information.
TARGET CONTENT TYPES:
- GitHub repository files (YAML configurations, Python implementations, README files)
- ADK documentation pages and API references
- Code examples and implementation patterns
- Configuration samples and templates
- Troubleshooting guides and solutions
When given a URL, use the url_context tool to:
1. Fetch the complete content from the specified URL
2. Analyze the content thoroughly for relevant information
3. Extract specific details about:
- Agent configurations and structure
- Tool implementations and usage patterns
- Architecture decisions and relationships
- Code snippets and examples
- Best practices and recommendations
- Error handling and troubleshooting steps
Return a comprehensive analysis that includes:
- Summary of what the content provides
- Specific implementation details and code patterns
- Key configuration examples or snippets
- How the content relates to the original query
- Actionable insights and recommendations
- Any warnings or important considerations mentioned
Focus on extracting complete, detailed information that enables practical application of the patterns and examples found.""",
model="gemini-2.5-flash",
tools=[url_context],
)
@@ -0,0 +1,37 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tools for Agent Builder Assistant."""
from .cleanup_unused_files import cleanup_unused_files
from .delete_files import delete_files
from .explore_project import explore_project
from .read_config_files import read_config_files
from .read_files import read_files
from .resolve_root_directory import resolve_root_directory
from .search_adk_source import search_adk_source
from .write_config_files import write_config_files
from .write_files import write_files
__all__ = [
'read_config_files',
'write_config_files',
'cleanup_unused_files',
'delete_files',
'read_files',
'write_files',
'search_adk_source',
'explore_project',
'resolve_root_directory',
]
@@ -0,0 +1,108 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cleanup unused files tool for Agent Builder Assistant."""
from pathlib import Path
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
async def cleanup_unused_files(
root_directory: str,
used_files: List[str],
file_patterns: Optional[List[str]] = None,
exclude_patterns: Optional[List[str]] = None,
) -> Dict[str, Any]:
"""Identify and optionally delete unused files in project directories.
This tool helps clean up unused tool files when agent configurations change.
It identifies files that match patterns but aren't referenced in used_files
list.
Args:
root_directory: Root directory to scan for unused files
used_files: List of file paths currently in use (should not be deleted)
file_patterns: List of glob patterns to match files (default: ["*.py"])
exclude_patterns: List of patterns to exclude (default: ["__init__.py"])
Returns:
Dict containing cleanup results:
- success: bool indicating if scan succeeded
- root_directory: absolute path to scanned directory
- unused_files: list of unused files found
- deleted_files: list of files actually deleted
- backup_files: list of backup files created
- errors: list of error messages
- total_freed_space: total bytes freed by deletions
"""
try:
root_path = Path(root_directory).resolve()
used_files_set = {Path(f).resolve() for f in used_files}
# Set defaults
if file_patterns is None:
file_patterns = ["*.py"]
if exclude_patterns is None:
exclude_patterns = ["__init__.py", "*_test.py", "test_*.py"]
result = {
"success": False,
"root_directory": str(root_path),
"unused_files": [],
"deleted_files": [],
"backup_files": [],
"errors": [],
"total_freed_space": 0,
}
if not root_path.exists():
result["errors"].append(f"Root directory does not exist: {root_path}")
return result
# Find all files matching patterns
all_files = []
for pattern in file_patterns:
all_files.extend(root_path.rglob(pattern))
# Filter out excluded patterns
for exclude_pattern in exclude_patterns:
all_files = [f for f in all_files if not f.match(exclude_pattern)]
# Identify unused files
unused_files = []
for file_path in all_files:
if file_path not in used_files_set:
unused_files.append(file_path)
result["unused_files"] = [str(f) for f in unused_files]
# Note: This function only identifies unused files
# Actual deletion should be done with explicit user confirmation using delete_files()
result["success"] = True
return result
except Exception as e:
return {
"success": False,
"root_directory": root_directory,
"unused_files": [],
"deleted_files": [],
"backup_files": [],
"errors": [f"Cleanup scan failed: {str(e)}"],
"total_freed_space": 0,
}
@@ -0,0 +1,127 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""File deletion tool for Agent Builder Assistant."""
from datetime import datetime
from pathlib import Path
import shutil
from typing import Any
from typing import Dict
from typing import List
async def delete_files(
file_paths: List[str],
create_backup: bool = False,
confirm_deletion: bool = True,
) -> Dict[str, Any]:
"""Delete multiple files with optional backup creation.
This tool safely deletes multiple files with validation and optional backup
creation.
It's designed for cleaning up unused tool files when agent configurations
change.
Args:
file_paths: List of absolute or relative paths to files to delete
create_backup: Whether to create a backup before deletion (default: False)
confirm_deletion: Whether deletion was confirmed by user (default: True for
safety)
Returns:
Dict containing deletion operation results:
- success: bool indicating if all deletions succeeded
- files: dict mapping file_path to file deletion info:
- existed: bool indicating if file existed before deletion
- backup_created: bool indicating if backup was created
- backup_path: path to backup file if created
- error: error message if deletion failed for this file
- file_size: size of deleted file in bytes (if existed)
- successful_deletions: number of files deleted successfully
- total_files: total number of files requested
- errors: list of general error messages
"""
try:
result = {
"success": True,
"files": {},
"successful_deletions": 0,
"total_files": len(file_paths),
"errors": [],
}
# Safety check - only delete if user confirmed
if not confirm_deletion:
result["success"] = False
result["errors"].append("Deletion not confirmed by user")
return result
for file_path in file_paths:
file_path_obj = Path(file_path).resolve()
file_info = {
"existed": False,
"backup_created": False,
"backup_path": None,
"error": None,
"file_size": 0,
}
try:
# Check if file exists
if not file_path_obj.exists():
file_info["error"] = f"File does not exist: {file_path_obj}"
result["files"][str(file_path_obj)] = file_info
result["successful_deletions"] += 1 # Still count as success
continue
file_info["existed"] = True
file_info["file_size"] = file_path_obj.stat().st_size
# Create backup if requested
if create_backup:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_path = file_path_obj.with_suffix(
f".backup_{timestamp}{file_path_obj.suffix}"
)
try:
shutil.copy2(file_path_obj, backup_path)
file_info["backup_created"] = True
file_info["backup_path"] = str(backup_path)
except Exception as e:
file_info["error"] = f"Failed to create backup: {str(e)}"
result["success"] = False
result["files"][str(file_path_obj)] = file_info
continue
# Delete the file
file_path_obj.unlink()
result["successful_deletions"] += 1
except Exception as e:
file_info["error"] = f"Deletion failed: {str(e)}"
result["success"] = False
result["files"][str(file_path_obj)] = file_info
return result
except Exception as e:
return {
"success": False,
"files": {},
"successful_deletions": 0,
"total_files": len(file_paths) if file_paths else 0,
"errors": [f"Delete operation failed: {str(e)}"],
}
@@ -0,0 +1,354 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Project explorer tool for analyzing structure and suggesting file paths."""
from pathlib import Path
from typing import Any
from typing import Dict
from typing import List
async def explore_project(root_directory: str) -> Dict[str, Any]:
"""Analyze project structure and suggest optimal file paths for ADK agents.
This tool performs comprehensive project analysis to understand the existing
structure and recommend appropriate locations for new agent configurations,
tools, and related files following ADK best practices.
Args:
root_directory: Absolute or relative path to the root directory to explore
and analyze
Returns:
Dict containing analysis results:
Always included:
- success: bool indicating if exploration succeeded
- root_path: absolute path to the analyzed directory
Success cases only (success=True):
- project_info: dict with basic project metadata. Contains:
• "name": project directory name
• "absolute_path": full path to project root
• "is_empty": bool indicating if directory is empty
• "total_files": count of all files in project
• "total_directories": count of all subdirectories
• "has_python_files": bool indicating presence of .py
files
• "has_yaml_files": bool indicating presence of
.yaml/.yml files
• "has_tools_directory": bool indicating if tools/ exists
• "has_callbacks_directory": bool indicating if
callbacks/ exists
- existing_configs: list of dicts for found YAML configuration files.
Each dict contains:
• "filename": name of the config file
• "path": absolute path to the file
• "relative_path": path relative to project root
• "size": file size in bytes
• "is_valid_yaml": bool indicating if YAML parses
correctly
• "agent_name": extracted agent name (or None)
• "agent_class": agent class type (default:
"LlmAgent")
• "has_sub_agents": bool indicating if config has
sub_agents
• "has_tools": bool indicating if config has tools
- directory_structure: dict with hierarchical project tree view
- suggestions: dict with recommended paths for new components. Contains:
• "root_agent_configs": list of suggested main agent
filenames
• "sub_agent_patterns": list of naming pattern templates
• "directories": dict with tool/callback directory info
• "naming_examples": dict with example agent sets by
domain
- conventions: dict with ADK naming and organization best practices
Error cases only (success=False):
- error: descriptive error message explaining the failure
Examples:
Basic project exploration:
result = await explore_project("/path/to/my_adk_project")
Check project structure:
if result["project_info"]["has_tools_directory"]:
print("Tools directory already exists")
Analyze existing configs:
for config in result["existing_configs"]:
if config["is_valid_yaml"]:
print(f"Found agent: {config['agent_name']}")
Get path suggestions:
suggestions = result["suggestions"]["root_agent_configs"]
directories = result["suggestions"]["directories"]["tools"]
"""
try:
root_path = Path(root_directory).resolve()
if not root_path.exists():
return {
"success": False,
"error": f"Root directory does not exist: {root_directory}",
"root_path": str(root_path),
}
if not root_path.is_dir():
return {
"success": False,
"error": f"Path is not a directory: {root_directory}",
"root_path": str(root_path),
}
# Analyze project structure
project_info = _analyze_project_info(root_path)
existing_configs = _find_existing_configs(root_path)
directory_structure = _build_directory_tree(root_path)
suggestions = _generate_path_suggestions(root_path, existing_configs)
conventions = _get_naming_conventions()
return {
"success": True,
"root_path": str(root_path),
"project_info": project_info,
"existing_configs": existing_configs,
"directory_structure": directory_structure,
"suggestions": suggestions,
"conventions": conventions,
}
except PermissionError:
return {
"success": False,
"error": f"Permission denied accessing directory: {root_directory}",
"root_path": root_directory,
}
except Exception as e:
return {
"success": False,
"error": f"Error exploring project: {str(e)}",
"root_path": root_directory,
}
def _analyze_project_info(root_path: Path) -> Dict[str, Any]:
"""Analyze basic project information."""
info = {
"name": root_path.name,
"absolute_path": str(root_path),
"is_empty": not any(root_path.iterdir()),
"total_files": 0,
"total_directories": 0,
"has_python_files": False,
"has_yaml_files": False,
"has_tools_directory": False,
"has_callbacks_directory": False,
}
try:
for item in root_path.rglob("*"):
if item.is_file():
info["total_files"] += 1
suffix = item.suffix.lower()
if suffix == ".py":
info["has_python_files"] = True
elif suffix in [".yaml", ".yml"]:
info["has_yaml_files"] = True
elif item.is_dir():
info["total_directories"] += 1
if item.name == "tools" and item.parent == root_path:
info["has_tools_directory"] = True
elif item.name == "callbacks" and item.parent == root_path:
info["has_callbacks_directory"] = True
except Exception:
# Continue with partial information if traversal fails
pass
return info
def _find_existing_configs(root_path: Path) -> List[Dict[str, Any]]:
"""Find existing YAML configuration files in the project."""
configs = []
try:
# Look for YAML files in root directory (ADK convention)
for yaml_file in root_path.glob("*.yaml"):
if yaml_file.is_file():
config_info = _analyze_config_file(yaml_file)
configs.append(config_info)
for yml_file in root_path.glob("*.yml"):
if yml_file.is_file():
config_info = _analyze_config_file(yml_file)
configs.append(config_info)
# Sort by name for consistent ordering
configs.sort(key=lambda x: x["filename"])
except Exception:
# Return partial results if scanning fails
pass
return configs
def _analyze_config_file(config_path: Path) -> Dict[str, Any]:
"""Analyze a single configuration file."""
info = {
"filename": config_path.name,
"path": str(config_path),
"relative_path": config_path.name, # In root directory
"size": 0,
"is_valid_yaml": False,
"agent_name": None,
"agent_class": None,
"has_sub_agents": False,
"has_tools": False,
}
try:
info["size"] = config_path.stat().st_size
# Try to parse YAML to extract basic info
import yaml
with open(config_path, "r", encoding="utf-8") as f:
content = yaml.safe_load(f)
if isinstance(content, dict):
info["is_valid_yaml"] = True
info["agent_name"] = content.get("name")
info["agent_class"] = content.get("agent_class", "LlmAgent")
info["has_sub_agents"] = bool(content.get("sub_agents"))
info["has_tools"] = bool(content.get("tools"))
except Exception:
# File exists but couldn't be parsed
pass
return info
def _build_directory_tree(
root_path: Path, max_depth: int = 3
) -> Dict[str, Any]:
"""Build a directory tree representation."""
def build_tree_recursive(
path: Path, current_depth: int = 0
) -> Dict[str, Any]:
if current_depth > max_depth:
return {"truncated": True}
tree = {
"name": path.name,
"type": "directory" if path.is_dir() else "file",
"path": str(path.relative_to(root_path)),
}
if path.is_dir():
children = []
try:
for child in sorted(path.iterdir()):
# Skip hidden files and common ignore patterns
if not child.name.startswith(".") and child.name not in [
"__pycache__",
"node_modules",
]:
children.append(build_tree_recursive(child, current_depth + 1))
tree["children"] = children
except PermissionError:
tree["error"] = "Permission denied"
else:
tree["size"] = path.stat().st_size if path.exists() else 0
return tree
return build_tree_recursive(root_path)
def _generate_path_suggestions(
root_path: Path, existing_configs: List[Dict[str, Any]]
) -> Dict[str, Any]:
"""Generate suggested file paths for new components."""
# Suggest main agent names if none exist
root_agent_suggestions = []
if not any(
config.get("agent_class") != "LlmAgent"
or not config.get("has_sub_agents", False)
for config in existing_configs
):
root_agent_suggestions = [
"root_agent.yaml",
]
# Directory suggestions
directories = {
"tools": {
"path": str(root_path / "tools"),
"exists": (root_path / "tools").exists(),
"purpose": "Custom tool implementations",
"example_files": [
"custom_email.py",
"database_connector.py",
],
},
"callbacks": {
"path": str(root_path / "callbacks"),
"exists": (root_path / "callbacks").exists(),
"purpose": "Custom callback functions",
"example_files": ["logging.py", "security.py"],
},
}
return {
"root_agent_configs": root_agent_suggestions,
"sub_agent_patterns": [
"{purpose}_agent.yaml",
"{domain}_{action}_agent.yaml",
"{workflow_step}_agent.yaml",
],
"directories": directories,
}
def _get_naming_conventions() -> Dict[str, Any]:
"""Get ADK naming conventions and best practices."""
return {
"agent_files": {
"format": "snake_case with .yaml extension",
"examples": ["main_agent.yaml", "email_processor.yaml"],
"location": "Root directory of the project",
"avoid": ["camelCase.yaml", "spaces in names.yaml", "UPPERCASE.yaml"],
},
"agent_names": {
"format": "snake_case, descriptive, no spaces",
"examples": ["customer_service_coordinator", "email_classifier"],
"avoid": ["Agent1", "my agent", "CustomerServiceAgent"],
},
"directory_structure": {
"recommended": {
"root": "All .yaml agent configuration files",
"tools/": "Custom tool implementations (.py files)",
"callbacks/": "Custom callback functions (.py files)",
}
},
}

Some files were not shown because too many files have changed in this diff Show More