docs: Update ADK release analyzer to use Gemini 3 Pro with retry and improve file filtering

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 861784867
This commit is contained in:
Xuan Yang
2026-01-27 10:31:03 -08:00
committed by Copybara-Service
parent 3bcd8f7f7a
commit 2155a35c51
3 changed files with 37 additions and 13 deletions
@@ -57,8 +57,25 @@ from google.adk import Agent
from google.adk.agents.loop_agent import LoopAgent
from google.adk.agents.readonly_context import ReadonlyContext
from google.adk.agents.sequential_agent import SequentialAgent
from google.adk.models import Gemini
from google.adk.tools.exit_loop_tool import exit_loop
from google.adk.tools.tool_context import ToolContext
from google.genai import types
# Retry configuration for handling API rate limits and overload
_RETRY_OPTIONS = types.HttpRetryOptions(
initial_delay=10,
attempts=8,
exp_base=2,
max_delay=300,
http_status_codes=[429, 503],
)
# Use gemini-3-pro-preview for planning and summary (better quality)
GEMINI_PRO_WITH_RETRY = Gemini(
model="gemini-3-pro-preview",
retry_options=_RETRY_OPTIONS,
)
# Maximum number of files per analysis group to avoid context overflow
MAX_FILES_PER_GROUP = 5
@@ -249,7 +266,7 @@ def get_release_context(tool_context: ToolContext) -> dict[str, Any]:
# =============================================================================
planner_agent = Agent(
model="gemini-2.5-pro",
model=GEMINI_PRO_WITH_RETRY,
name="release_planner",
description=(
"Plans the analysis by fetching release info and organizing files into"
@@ -272,12 +289,12 @@ efficient processing.
3. Call `get_changed_files_summary` to get the list of changed files WITHOUT
the full patches (to save context space).
- **IMPORTANT**: Pass `local_repo_path="{LOCAL_REPOS_DIR_PATH}/{CODE_REPO}"`
to use local git and avoid GitHub API's 300-file limit.
- **IMPORTANT**: Pass these parameters:
- `local_repo_path="{LOCAL_REPOS_DIR_PATH}/{CODE_REPO}"` to avoid 300-file limit
- `path_filter="src/google/adk/"` to only get ADK source files (reduces token usage)
4. Filter and organize the files:
- **INCLUDE** only files in `src/google/adk/` directory
- **EXCLUDE** test files, `__init__.py`, and files outside src/
4. Further filter the returned files:
- **EXCLUDE** test files and `__init__.py` files
- **IMPORTANT**: Do NOT exclude any file just because it has few changes.
Even single-line changes to public APIs need documentation updates.
- **PRIORITIZE** by importance:
@@ -423,7 +440,7 @@ files and finding related documentation that needs updating.
file_group_analyzer = Agent(
model="gemini-2.5-pro",
model=GEMINI_PRO_WITH_RETRY,
name="file_group_analyzer",
description=(
"Analyzes a group of changed files and generates recommendations."
@@ -507,7 +524,7 @@ Present a summary of:
summary_agent = Agent(
model="gemini-2.5-pro",
model=GEMINI_PRO_WITH_RETRY,
name="summary_agent",
description="Compiles recommendations and creates the GitHub issue.",
instruction=summary_instruction,
@@ -542,7 +559,7 @@ analysis_pipeline = SequentialAgent(
# =============================================================================
root_agent = Agent(
model="gemini-2.5-pro",
model=GEMINI_PRO_WITH_RETRY,
name="adk_release_analyzer",
description=(
"Analyzes ADK Python releases and generates documentation update"
@@ -605,6 +605,7 @@ def get_changed_files_summary(
start_tag: str,
end_tag: str,
local_repo_path: Optional[str] = None,
path_filter: Optional[str] = None,
) -> Dict[str, Any]:
"""Gets a summary of changed files between two releases without patches.
@@ -620,6 +621,9 @@ def get_changed_files_summary(
local_repo_path: Optional absolute path to local git repo. If provided
and valid, uses git diff instead of GitHub API to get complete
file list (avoids 300-file limit).
path_filter: Optional path prefix to filter files. Only files whose
path starts with this prefix will be included. Example:
"src/google/adk/" to only include ADK source files.
Returns:
A dictionary containing the status and a summary of changed files.
@@ -627,7 +631,7 @@ def get_changed_files_summary(
# Use local git if valid path is provided (avoids GitHub API 300-file limit)
if local_repo_path and os.path.isdir(os.path.join(local_repo_path, ".git")):
return _get_changed_files_from_local_git(
local_repo_path, start_tag, end_tag, repo_owner, repo_name
local_repo_path, start_tag, end_tag, repo_owner, repo_name, path_filter
)
# Fall back to GitHub API (limited to 300 files)
@@ -689,6 +693,7 @@ def _get_changed_files_from_local_git(
end_tag: str,
repo_owner: str,
repo_name: str,
path_filter: Optional[str] = None,
) -> Dict[str, Any]:
"""Gets changed files using local git commands (no file limit).
@@ -698,6 +703,7 @@ def _get_changed_files_from_local_git(
end_tag: The newer tag (head) for the comparison.
repo_owner: Repository owner for compare URL.
repo_name: Repository name for compare URL.
path_filter: Optional path prefix to filter files.
Returns:
A dictionary containing the status and a summary of changed files.
@@ -766,6 +772,10 @@ def _get_changed_files_from_local_git(
status_code = parts[0][0] # First char is the status
filename = parts[-1] # Last part is filename (handles renames)
# Apply path filter if specified
if path_filter and not filename.startswith(path_filter):
continue
stats = file_stats.get(
filename,
{
-3
View File
@@ -701,7 +701,6 @@ def cli_eval(
separated list of eval names and then add that as a suffix to the eval set
file name, demarcated by a `:`.
\b
For example, we have `sample_eval_set_file.json` file that has following the
eval cases:
sample_eval_set_file.json:
@@ -722,7 +721,6 @@ def cli_eval(
separated list of eval names and then add that as a suffix to the eval set
file name, demarcated by a `:`.
\b
For example, we have `sample_eval_set_id` that has following the eval cases:
sample_eval_set_id:
|....... eval_1
@@ -731,7 +729,6 @@ def cli_eval(
|....... eval_4
|....... eval_5
\b
If we did:
sample_eval_set_id:eval_1,eval_2,eval_3