Files
adk-python/contributing/samples/adk_triaging_agent/agent.py
T
Selcuk GunandCopybara-Service 131957c531 chore: Triaging agent improvements & github workflow
* modified list issues to only return unlabelled open issues
* added github workflow to run on schedule and issue open/reopen
* interactive/workflow modes
* readme document

PiperOrigin-RevId: 771152306
2025-06-13 10:56:32 -07:00

146 lines
4.5 KiB
Python

# 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 os
from google.adk import Agent
import requests
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
if not GITHUB_TOKEN:
raise ValueError("GITHUB_TOKEN environment variable not set")
OWNER = os.getenv("OWNER", "google")
REPO = os.getenv("REPO", "adk-python")
BOT_LABEL = os.getenv("BOT_LABEL", "bot_triaged")
BASE_URL = "https://api.github.com"
headers = {
"Authorization": f"token {GITHUB_TOKEN}",
"Accept": "application/vnd.github.v3+json",
}
ALLOWED_LABELS = [
"documentation",
"services",
"question",
"tools",
"eval",
"live",
"models",
"tracing",
"core",
"web",
]
def is_interactive():
return os.environ.get("INTERACTIVE", "1").lower() in ["true", "1"]
def list_issues(issue_count: int):
"""
Generator to list all issues for the repository by handling pagination.
Args:
issue_count: number of issues to return
"""
query = f"repo:{OWNER}/{REPO} is:open is:issue no:label"
unlabelled_issues = []
url = f"{BASE_URL}/search/issues"
params = {
"q": query,
"sort": "created",
"order": "desc",
"per_page": issue_count,
"page": 1,
}
response = requests.get(url, headers=headers, params=params, timeout=60)
response.raise_for_status()
json_response = response.json()
issues = json_response.get("items", None)
if not issues:
return []
for issue in issues:
if not issue.get("labels", None) or len(issue["labels"]) == 0:
unlabelled_issues.append(issue)
return unlabelled_issues
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
"""
print(f"Attempting to add label '{label}' to issue #{issue_number}")
if label not in ALLOWED_LABELS:
error_message = (
f"Error: Label '{label}' is not an allowed label. Will not apply."
)
print(error_message)
return {"status": "error", "message": error_message, "applied_label": None}
url = f"{BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/labels"
payload = [label, BOT_LABEL]
response = requests.post(url, headers=headers, json=payload, timeout=60)
response.raise_for_status()
return response.json()
approval_instruction = (
"Only label them when the user approves the labeling!"
if is_interactive()
else (
"Do not ask for user approval for labeling! If you can't find a"
" appropriate labels for the issue, do not label it."
)
)
root_agent = Agent(
model="gemini-2.5-pro-preview-05-06",
name="adk_triaging_assistant",
description="Triage ADK issues.",
instruction=f"""
You are a Github adk-python repo triaging bot. You will help get issues, and recommend a label.
IMPORTANT: {approval_instruction}
Here are the rules for labeling:
- 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 "web"
- If the user is asking about a question, 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, follow the previous instruction that starts with "IMPORTANT:".
Present the followings in an easy to read format highlighting issue number and your label.
- the issue summary in a few sentence
- your label recommendation and justification
""",
tools=[
list_issues,
add_label_to_issue,
],
)