diff --git a/contributing/samples/adk_documentation/adk_release_analyzer/agent.py b/contributing/samples/adk_documentation/adk_release_analyzer/agent.py index 738506e9..bac80901 100644 --- a/contributing/samples/adk_documentation/adk_release_analyzer/agent.py +++ b/contributing/samples/adk_documentation/adk_release_analyzer/agent.py @@ -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" diff --git a/contributing/samples/adk_documentation/tools.py b/contributing/samples/adk_documentation/tools.py index f9a09b54..74703b95 100644 --- a/contributing/samples/adk_documentation/tools.py +++ b/contributing/samples/adk_documentation/tools.py @@ -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, { diff --git a/src/google/adk/cli/cli_tools_click.py b/src/google/adk/cli/cli_tools_click.py index 2a2b2ac8..c4f1d405 100644 --- a/src/google/adk/cli/cli_tools_click.py +++ b/src/google/adk/cli/cli_tools_click.py @@ -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