mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
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:
committed by
Copybara-Service
parent
3bcd8f7f7a
commit
2155a35c51
@@ -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,
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user