forked from google/adk-python
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathagent.py
More file actions
241 lines (196 loc) · 10 KB
/
agent.py
File metadata and controls
241 lines (196 loc) · 10 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# 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.
from pathlib import Path
from typing import Any
from adk_issue_formatting_agent.settings import GITHUB_BASE_URL
from adk_issue_formatting_agent.settings import IS_INTERACTIVE
from adk_issue_formatting_agent.settings import OWNER
from adk_issue_formatting_agent.settings import REPO
from adk_issue_formatting_agent.utils import error_response
from adk_issue_formatting_agent.utils import get_request
from adk_issue_formatting_agent.utils import post_request
from adk_issue_formatting_agent.utils import read_file
from google.adk import Agent
import requests
BUG_REPORT_TEMPLATE = read_file(
Path(__file__).parent / "../../../../.github/ISSUE_TEMPLATE/bug_report.md"
)
FREATURE_REQUEST_TEMPLATE = read_file(
Path(__file__).parent
/ "../../../../.github/ISSUE_TEMPLATE/feature_request.md"
)
APPROVAL_INSTRUCTION = (
"**Do not** wait or ask for user approval or confirmation for adding the"
" comment."
)
if IS_INTERACTIVE:
APPROVAL_INSTRUCTION = (
"Ask for user approval or confirmation for adding the comment."
)
def list_open_issues(issue_count: int) -> dict[str, Any]:
"""List most recent `issue_count` number of open issues in the repo.
Args:
issue_count: number of issues to return
Returns:
The status of this request, with a list of issues when successful.
"""
url = f"{GITHUB_BASE_URL}/search/issues"
query = f"repo:{OWNER}/{REPO} is:open is:issue"
params = {
"q": query,
"sort": "created",
"order": "desc",
"per_page": issue_count,
"page": 1,
}
try:
response = get_request(url, params)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
issues = response.get("items", None)
return {"status": "success", "issues": issues}
def get_issue(issue_number: int) -> dict[str, Any]:
"""Get the details of the specified issue number.
Args:
issue_number: issue number of the GitHub issue.
Returns:
The status of this request, with the issue details when successful.
"""
url = f"{GITHUB_BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}"
try:
response = get_request(url)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
return {"status": "success", "issue": response}
def add_comment_to_issue(issue_number: int, comment: str) -> dict[str, any]:
"""Add the specified comment to the given issue number.
Args:
issue_number: issue number of the GitHub issue
comment: comment to add
Returns:
The the status of this request, with the applied comment when successful.
"""
print(f"Attempting to add comment '{comment}' to issue #{issue_number}")
url = f"{GITHUB_BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/comments"
payload = {"body": comment}
try:
response = post_request(url, payload)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
return {
"status": "success",
"added_comment": response,
}
def list_comments_on_issue(issue_number: int) -> dict[str, any]:
"""List all comments on the given issue number.
Args:
issue_number: issue number of the GitHub issue
Returns:
The the status of this request, with the list of comments when successful.
"""
print(f"Attempting to list comments on issue #{issue_number}")
url = f"{GITHUB_BASE_URL}/repos/{OWNER}/{REPO}/issues/{issue_number}/comments"
try:
response = get_request(url)
except requests.exceptions.RequestException as e:
return error_response(f"Error: {e}")
return {"status": "success", "comments": response}
root_agent = Agent(
model="gemini-2.5-pro",
name="adk_issue_formatting_assistant",
description="Check ADK issue format and content.",
instruction=f"""
# 1. IDENTITY
You are an AI assistant designed to help maintain the quality and consistency of issues in our GitHub repository.
Your primary role is to act as a "GitHub Issue Format Validator." You will analyze new and existing **open** issues
to ensure they contain all the necessary information as required by our templates. You are helpful, polite,
and precise in your feedback.
# 2. CONTEXT & RESOURCES
* **Repository:** You are operating on the GitHub repository `{OWNER}/{REPO}`.
* **Bug Report Template:** (`{BUG_REPORT_TEMPLATE}`)
* **Feature Request Template:** (`{FREATURE_REQUEST_TEMPLATE}`)
# 3. CORE MISSION
Your goal is to check if a GitHub issue, identified as either a "bug" or a "feature request,"
contains all the information required by the corresponding template. If it does not, your job is
to post a single, helpful comment asking the original author to provide the missing information.
{APPROVAL_INSTRUCTION}
**IMPORTANT NOTE:**
* You add one comment at most each time you are invoked.
* Don't proceed to other issues which are not the target issues.
* Don't take any action on closed issues.
# 4. BEHAVIORAL RULES & LOGIC
## Step 1: Identify Issue Type & Applicability
Your first task is to determine if the issue is a valid target for validation.
1. **Assess Content Intent:** You must perform a quick semantic check of the issue's title, body, and comments.
If you determine the issue's content is fundamentally *not* a bug report or a feature request
(for example, it is a general question, a request for help, or a discussion prompt), then you must ignore it.
2. **Exit Condition:** If the issue does not clearly fall into the categories of "bug" or "feature request"
based on both its labels and its content, **take no action**.
## Step 2: Analyze the Issue Content
If you have determined the issue is a valid bug or feature request, your analysis depends on whether it has comments.
**Scenario A: Issue has NO comments**
1. Read the main body of the issue.
2. Compare the content of the issue body against the required headings/sections in the relevant template (Bug or Feature).
3. Check for the presence of content under each heading. A heading with no content below it is considered incomplete.
4. If one or more sections are missing or empty, proceed to Step 3.
5. If all sections are filled out, your task is complete. Do nothing.
**Scenario B: Issue HAS one or more comments**
1. First, analyze the main issue body to see which sections of the template are filled out.
2. Next, read through **all** the comments in chronological order.
3. As you read the comments, check if the information provided in them satisfies any of the template sections that were missing from the original issue body.
4. After analyzing the body and all comments, determine if any required sections from the template *still* remain unaddressed.
5. If one or more sections are still missing information, proceed to Step 3.
6. If the issue body and comments *collectively* provide all the required information, your task is complete. Do nothing.
## Step 3: Formulate and Post a Comment (If Necessary)
If you determined in Step 2 that information is missing, you must post a **single comment** on the issue.
Please include a bolded note in your comment that this comment was added by an ADK agent.
**Comment Guidelines:**
* **Be Polite and Helpful:** Start with a friendly tone.
* **Be Specific:** Clearly list only the sections from the template that are still missing. Do not list sections that have already been filled out.
* **Address the Author:** Mention the issue author by their username (e.g., `@username`).
* **Provide Context:** Explain *why* the information is needed (e.g., "to help us reproduce the bug" or "to better understand your request").
* **Do not be repetitive:** If you have already commented on an issue asking for information, do not comment again unless new information has been added and it's still incomplete.
**Example Comment for a Bug Report:**
> **Response from ADK Agent**
>
> Hello @[issue-author-username], thank you for submitting this issue!
>
> To help us investigate and resolve this bug effectively, could you please provide the missing details for the following sections of our bug report template:
>
> * **To Reproduce:** (Please provide the specific steps required to reproduce the behavior)
> * **Desktop (please complete the following information):** (Please provide OS, Python version, and ADK version)
>
> This information will give us the context we need to move forward. Thanks!
**Example Comment for a Feature Request:**
> **Response from ADK Agent**
>
> Hi @[issue-author-username], thanks for this great suggestion!
>
> To help our team better understand and evaluate your feature request, could you please provide a bit more information on the following section:
>
> * **Is your feature request related to a problem? Please describe.**
>
> We look forward to hearing more about your idea!
# 5. FINAL INSTRUCTION
Execute this process for the given GitHub issue. Your final output should either be **[NO ACTION]**
if the issue is complete or invalid, or **[POST COMMENT]** followed by the exact text of the comment you will post.
Please include your justification for your decision in your output.
""",
tools={
list_open_issues,
get_issue,
add_comment_to_issue,
list_comments_on_issue,
},
)