Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/stale-bot.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# 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.

name: ADK Stale Issue Auditor

on:
Expand Down
17 changes: 11 additions & 6 deletions contributing/samples/adk_stale_agent/PROMPT_INSTRUCTION.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,21 @@ Your job is to analyze a specific issue and report findings before taking action

**STEP 3: ANALYZE MAINTAINER INTENT**
- **Context**: The last person to act was a Maintainer.
- **Action**: Read the text in `last_comment_text`.
- **Question Check**: Does the text ask a question, request clarification, ask for logs, or suggest trying a fix?
- **Action**: Analyze `last_comment_text` using `maintainers` list and `last_actor_name`.

- **Internal Discussion Check**: Does the comment mention or address any username found in the `maintainers` list (other than the speaker `last_actor_name`)?
- **Verdict**: **ACTIVE** (Internal Team Discussion).
- **Report**: "Analysis for Issue #[number]: ACTIVE. Maintainer is discussing with another maintainer. No action."

- **Question Check**: Does the text ask a question, request clarification, ask for logs, or give suggestions?
- **Time Check**: Is `days_since_activity` > {stale_threshold_days}?

- **DECISION**:
- **IF (Question == YES) AND (Time == YES)**:
- **IF (Question == YES) AND (Time == YES) AND (Internal Discussion Check == FALSE):**
- **Action**: Call `add_stale_label_and_comment`.
- **Check**: If '{REQUEST_CLARIFICATION_LABEL}' is not in `current_labels`, call `add_label_to_issue` for it.
- **Check**: If '{REQUEST_CLARIFICATION_LABEL}' is not in `current_labels`, call `add_label_to_issue` with '{REQUEST_CLARIFICATION_LABEL}'.
- **Report**: "Analysis for Issue #[number]: STALE. Maintainer asked question [days_since_activity] days ago. Marking stale."
- **IF (Question == YES) BUT (Time == NO)**:
- **Report**: "Analysis for Issue #[number]: PENDING. Maintainer asked question, but threshold not met yet. No action."
- **IF (Question == NO)** (e.g., "I am working on this"):
- **Report**: "Analysis for Issue #[number]: ACTIVE. Maintainer gave status update (not a question). No action."
- **IF (Question == NO) OR (Internal Discussion Check == TRUE):**
- **Report**: "Analysis for Issue #[number]: ACTIVE. Maintainer gave status update or internal discussion detected. No action."
7 changes: 7 additions & 0 deletions contributing/samples/adk_stale_agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,13 @@ def _replay_history_to_find_state(
- last_activity_time (datetime): Timestamp of the last human action.
- last_action_type (str): The type of the last action (e.g., 'commented').
- last_comment_text (Optional[str]): The text of the last comment.
- last_actor_name (str): The specific username of the last actor.
"""
last_action_role = "author"
last_activity_time = history[0]["time"]
last_action_type = "created"
last_comment_text = None
last_actor_name = issue_author

for event in history:
actor = event["actor"]
Expand All @@ -337,6 +339,7 @@ def _replay_history_to_find_state(
last_action_role = role
last_activity_time = event["time"]
last_action_type = etype
last_actor_name = actor

# Only store text if it was a comment (resets on other events like labels/edits)
if etype == "commented":
Expand All @@ -349,6 +352,7 @@ def _replay_history_to_find_state(
"last_activity_time": last_activity_time,
"last_action_type": last_action_type,
"last_comment_text": last_comment_text,
"last_actor_name": last_actor_name,
}


Expand Down Expand Up @@ -428,6 +432,7 @@ def get_issue_state(item_number: int) -> Dict[str, Any]:
"status": "success",
"last_action_role": state["last_action_role"],
"last_action_type": state["last_action_type"],
"last_actor_name": state["last_actor_name"],
"maintainer_alert_needed": maintainer_alert_needed,
"is_stale": is_stale,
"days_since_activity": days_since_activity,
Expand All @@ -436,6 +441,8 @@ def get_issue_state(item_number: int) -> Dict[str, Any]:
"current_labels": labels_list,
"stale_threshold_days": STALE_HOURS_THRESHOLD / 24,
"close_threshold_days": CLOSE_HOURS_AFTER_STALE_THRESHOLD / 24,
"maintainers": maintainers,
"issue_author": issue_author,
}

except RequestException as e:
Expand Down
Loading