From cf689fd5283fb92cfbcea59a37b3e382911c4311 Mon Sep 17 00:00:00 2001 From: Hangfei Lin Date: Wed, 4 Jun 2025 21:25:02 -0700 Subject: [PATCH 1/3] chore: Create agent.py add a ADK triaging agent to help triaging issues. This is an MVP. We can iterate further. --- .../samples/adk_triaging_agent/agent.py | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 contributing/samples/adk_triaging_agent/agent.py diff --git a/contributing/samples/adk_triaging_agent/agent.py b/contributing/samples/adk_triaging_agent/agent.py new file mode 100644 index 00000000..2c874354 --- /dev/null +++ b/contributing/samples/adk_triaging_agent/agent.py @@ -0,0 +1,114 @@ +# 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. + +import random +import os +import requests +import time +from google.adk import Agent +from google.adk.tools.tool_context import ToolContext +from google.genai import types + + +# Read the PAT from the environment variable +GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") # Ensure you've set this in your shell +if not GITHUB_TOKEN: + raise ValueError("GITHUB_TOKEN environment variable not set") + +# Repository information +OWNER = "google" +REPO = "adk-python" + +# Base URL for the GitHub API +BASE_URL = "https://api.github.com" + +# Headers including the Authorization header +headers = { + "Authorization": f"token {GITHUB_TOKEN}", + "Accept": "application/vnd.github.v3+json" +} + + +def list_issues(per_page:int): + """ + Generator to list all issues for the repository by handling pagination. + + Args: + per_page: number of pages to return per page. + + """ + state="open" + # only process the 1st page for testing for now + page = 1 + results = [] + url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues" # :contentReference[oaicite:16]{index=16} + # Warning: let's only handle max 10 issues at a time to avoid bad results + params = { + "state": state, + "per_page": per_page, + "page": page + } + response = requests.get(url, headers=headers, params=params) + response.raise_for_status() # :contentReference[oaicite:17]{index=17} + issues = response.json() + if not issues: + return [] + for issue in issues: + # Skip pull requests (issues API returns PRs as well) + if "pull_request" in issue: + continue + results.append(issue) + return results + +def add_label_to_issue(issue_number:str, label:str): + """ + Add the specified label to the given issue number. + + Args: + issue_number: issue number of the Github issue, in string foramt. + label: label to assign + """ + url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/labels" + payload = [label] + response = requests.post(url, headers=headers, json=payload) + response.raise_for_status() + return response.json() + +root_agent = Agent( + model='gemini-2.5-pro-preview-05-06', + name='adk_triaging_assistant', + description=( + 'Triage ADK issues.' + ), + instruction=""" + You are a Github adk-python repo triaging bot. You will help get issues, and label them. + Here are the rules for labeling: + 1. If it's about session, memory services, label it with "services" + 2. If it's about UI/web, label it with "question" + 3. If it's related to tools, label it with "tools" + 4. In other cases, label it with "core". + """, + tools=[ + list_issues, + add_label_to_issue, + ], + generate_content_config=types.GenerateContentConfig( + safety_settings=[ + types.SafetySetting( # avoid false alarm about rolling dice. + category=types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, + threshold=types.HarmBlockThreshold.OFF, + ), + ] + ), +) From 0d232588e680c6dc3cd969ab46b8ba18742304a8 Mon Sep 17 00:00:00 2001 From: Hangfei Lin Date: Wed, 4 Jun 2025 21:34:33 -0700 Subject: [PATCH 2/3] chore: Update agent.py --- contributing/samples/adk_triaging_agent/agent.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/contributing/samples/adk_triaging_agent/agent.py b/contributing/samples/adk_triaging_agent/agent.py index 2c874354..2234af2e 100644 --- a/contributing/samples/adk_triaging_agent/agent.py +++ b/contributing/samples/adk_triaging_agent/agent.py @@ -94,10 +94,16 @@ root_agent = Agent( instruction=""" You are a Github adk-python repo triaging bot. You will help get issues, and label them. Here are the rules for labeling: - 1. If it's about session, memory services, label it with "services" - 2. If it's about UI/web, label it with "question" - 3. If it's related to tools, label it with "tools" - 4. In other cases, label it with "core". + - If the user is asking about documentation-related questions, label it with "documentation". + - If it's about session, memory services, label it with "services" + - If it's about UI/web, label it with "question" + - If it's related to tools, label it with "tools" + - If it's about agent evalaution, then label it with "eval". + - If it's about streaming/live, label it with "live". + - If it's about model support(non-Gemini, like Litellm, Ollama, OpenAI models), label it with "models". + - If it's about tracing, label it with "tracing". + - If it's agent orchestration, agent definition, label it with "core". + - If you can't find a appropriate labels for the issue, return the issues to user to decide. """, tools=[ list_issues, From 1d8d1e0a4eab6ce7b4e706f8f19116f34aa02812 Mon Sep 17 00:00:00 2001 From: Hangfei Lin Date: Wed, 4 Jun 2025 21:38:49 -0700 Subject: [PATCH 3/3] Update agent.py --- .../samples/adk_triaging_agent/agent.py | 98 +++++++++---------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/contributing/samples/adk_triaging_agent/agent.py b/contributing/samples/adk_triaging_agent/agent.py index 2234af2e..2720e5b4 100644 --- a/contributing/samples/adk_triaging_agent/agent.py +++ b/contributing/samples/adk_triaging_agent/agent.py @@ -12,19 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -import random import os -import requests +import random import time + from google.adk import Agent from google.adk.tools.tool_context import ToolContext from google.genai import types - +import requests # Read the PAT from the environment variable GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") # Ensure you've set this in your shell if not GITHUB_TOKEN: - raise ValueError("GITHUB_TOKEN environment variable not set") + raise ValueError("GITHUB_TOKEN environment variable not set") # Repository information OWNER = "google" @@ -36,61 +36,59 @@ BASE_URL = "https://api.github.com" # Headers including the Authorization header headers = { "Authorization": f"token {GITHUB_TOKEN}", - "Accept": "application/vnd.github.v3+json" + "Accept": "application/vnd.github.v3+json", } -def list_issues(per_page:int): - """ - Generator to list all issues for the repository by handling pagination. +def list_issues(per_page: int): + """ + Generator to list all issues for the repository by handling pagination. - Args: - per_page: number of pages to return per page. + Args: + per_page: number of pages to return per page. - """ - state="open" - # only process the 1st page for testing for now - page = 1 - results = [] - url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues" # :contentReference[oaicite:16]{index=16} - # Warning: let's only handle max 10 issues at a time to avoid bad results - params = { - "state": state, - "per_page": per_page, - "page": page - } - response = requests.get(url, headers=headers, params=params) - response.raise_for_status() # :contentReference[oaicite:17]{index=17} - issues = response.json() - if not issues: - return [] - for issue in issues: - # Skip pull requests (issues API returns PRs as well) - if "pull_request" in issue: - continue - results.append(issue) - return results + """ + state = "open" + # only process the 1st page for testing for now + page = 1 + results = [] + url = ( # :contentReference[oaicite:16]{index=16} + f"{BASE_URL}/repos/{OWNER}/{REPO}/issues" + ) + # Warning: let's only handle max 10 issues at a time to avoid bad results + params = {"state": state, "per_page": per_page, "page": page} + response = requests.get(url, headers=headers, params=params) + response.raise_for_status() # :contentReference[oaicite:17]{index=17} + issues = response.json() + if not issues: + return [] + for issue in issues: + # Skip pull requests (issues API returns PRs as well) + if "pull_request" in issue: + continue + results.append(issue) + return results -def add_label_to_issue(issue_number:str, label:str): - """ - Add the specified label to the given issue number. - Args: - issue_number: issue number of the Github issue, in string foramt. - label: label to assign - """ - url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/labels" - payload = [label] - response = requests.post(url, headers=headers, json=payload) - response.raise_for_status() - return response.json() +def add_label_to_issue(issue_number: str, label: str): + """ + Add the specified label to the given issue number. + + Args: + issue_number: issue number of the Github issue, in string foramt. + label: label to assign + """ + url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/labels" + payload = [label] + response = requests.post(url, headers=headers, json=payload) + response.raise_for_status() + return response.json() + root_agent = Agent( - model='gemini-2.5-pro-preview-05-06', - name='adk_triaging_assistant', - description=( - 'Triage ADK issues.' - ), + model="gemini-2.5-pro-preview-05-06", + name="adk_triaging_assistant", + description="Triage ADK issues.", instruction=""" You are a Github adk-python repo triaging bot. You will help get issues, and label them. Here are the rules for labeling: