feat: enhance agent notifications for issue comments and assignments
All checks were successful
Lint and Syntax Check / build (pull_request) Successful in 5s

This commit is contained in:
Space-Banane
2026-04-04 00:15:29 +02:00
parent 31d049d211
commit 61896a2139
2 changed files with 79 additions and 38 deletions

99
main.py
View File

@@ -11,8 +11,8 @@ DATABASE_STORAGE = os.getenv("DATABASE_STORAGE_NAME")
AGENT_USERNAME = os.getenv("AGENT_USERNAME")
AGENT_PROMPT_FILE = os.getenv("AGENT_PROMPT_FILE")
eventsToHandle = ["pull_request", "issues"]
actionsToHandle = ["assigned", "unassigned"]
eventsToHandle = ["pull_request", "issues", "issue_comment"]
actionsToHandle = ["assigned", "created"]
# Template Fields:
DEFAULT_PROMPT_TEMPLATE = """# GITEA STATUS UPDATE
@@ -31,7 +31,7 @@ The Goal is to solve this issue or PR as quickly and with as little back and for
def get_assignee_key(event_type, repository_id, number):
if event_type == "issues" or event_type == "issue":
if event_type == "issues" or event_type == "issue" or event_type == "issue_comment":
return f"assignees_issue_{repository_id}_{number}"
elif event_type == "pull_request":
return f"assignees_pr_{repository_id}_{number}"
@@ -89,6 +89,11 @@ def fill_template(template, event_object, action_str, type_str):
def build_message(event_object, action_str, type_str):
if type_str == "comment":
action_summary = f"There is a new comment on a {event_object['target_type']} you are assigned to in {event_object['repository']} by {event_object['sender']}."
else:
action_summary = f"You were {action_str} to an {type_str} in {event_object['repository']} by {event_object['sender']}."
if AGENT_PROMPT_FILE:
AGENT_PROMPT_FILE_PATH = "/app/" + AGENT_PROMPT_FILE
@@ -98,32 +103,45 @@ def build_message(event_object, action_str, type_str):
f"Custom prompt file not found at {AGENT_PROMPT_FILE_PATH}. Using default message."
)
message = fill_template(DEFAULT_PROMPT_TEMPLATE, event_object, action_str, type_str)
message = message.replace("You were [action_str] to an [type_str]", action_summary)
return message
with open(AGENT_PROMPT_FILE_PATH, "r") as f:
custom_prompt = f.read()
message = fill_template(custom_prompt, event_object, action_str, type_str)
message = message.replace("You were [action_str] to an [type_str]", action_summary)
return message
else:
print("No custom prompt file specified. Using default message.")
message = fill_template(DEFAULT_PROMPT_TEMPLATE, event_object, action_str, type_str)
message = message.replace("You were [action_str] to an [type_str]", action_summary)
return message
def sendToAgent(event_object):
headers = {"x-openclaw-token": OPENCLAW_TOKEN, "Content-Type": "application/json"}
action_str = "assigned" if event_object["action"] == "assigned" else "unassigned"
type_str = "issue" if event_object["type"] == "issue" else "pull request"
assignees = event_object.get("assignees", [event_object.get("assignee", "Unknown")])
if AGENT_USERNAME in assignees:
message = build_message(event_object, action_str, type_str)
if event_object.get("type") == "issue_comment":
action_str = "created"
type_str = "comment"
mention = f"@{AGENT_USERNAME}".lower()
comment_body = event_object.get("comment_body", "").lower()
if mention not in comment_body:
print(
f"Agent {AGENT_USERNAME} was not mentioned in comment body. Skipping notification."
)
return
else:
print(
f"Agent {AGENT_USERNAME} is not among the assignees for this event. Skipping notification."
)
return
action_str = "assigned"
type_str = "issue" if event_object["type"] == "issue" else "pull request"
assignees = event_object.get("assignees", [event_object.get("assignee", "Unknown")])
if AGENT_USERNAME not in assignees:
print(
f"Agent {AGENT_USERNAME} is not among the assignees for this event. Skipping notification."
)
return
message = build_message(event_object, action_str, type_str)
try:
if OPENCLAW_PROXY_AUTH:
@@ -239,7 +257,7 @@ def main(args):
"_headers": {"Content-Type": "application/json"},
}
if action in ["assigned", "unassigned"]:
if action == "assigned" and event_type in ["issues", "pull_request"]:
assignee_data = data.get("assignee")
assignees_data = data.get("assignees")
@@ -315,28 +333,12 @@ def main(args):
}
if event_object:
# Use helpers to store/delete assignees
# Store assignees for later comment events.
if action == "assigned":
set_stored_assignees(
db, event_type, repo_id, event_object["number"], assignees_list
)
if action == "unassigned":
# If the payload STILL has assignees, it means someone is still assigned
# If it's empty (or only contains "Unknown"), delete it.
if not assignees_data or len(assignees_data) == 0:
delete_stored_assignees(
db, event_type, repo_id, event_object["number"]
)
else:
set_stored_assignees(
db,
event_type,
repo_id,
event_object["number"],
assignees_list,
)
print(f"--- {event_object['type'].upper()} {action.capitalize()} ---")
print(f"Title: {event_object['title']}")
print(f"Assignees: {', '.join(event_object['assignees'])}")
@@ -344,8 +346,39 @@ def main(args):
print(f"By: {event_object['sender']}")
# Send to OpenClaw
# sendToAgent(event_object)
print("Not sending event to agent, unassinging is too noisy for now, will only send assigned events")
if action == "assigned":
sendToAgent(event_object)
else:
print(f"Action {action} is not configured to send to agent")
elif action == "created" and event_type == "issue_comment":
comment_data = data.get("comment", {})
is_pull = data.get("is_pull", False)
target_data = data.get("issue") or data.get("pull_request") or {}
repository = data.get("repository", {}).get("full_name", "Unknown")
repo_id = data.get("repository", {}).get("id")
sender = data.get("sender", {}).get("login", "Unknown")
issue_number = target_data.get("number")
event_object = {
"type": "issue_comment",
"target_type": "pull_request" if is_pull else "issue",
"action": action,
"repository": repository,
"number": issue_number,
"title": target_data.get("title", "Unknown"),
"sender": sender,
"comment_body": comment_data.get("body", ""),
"url": comment_data.get("html_url"),
}
print(f"--- {event_object['type'].upper()} {action.capitalize()} ---")
print(f"Title: {event_object['title']}")
print(f"Repo: {event_object['repository']}")
print(f"By: {event_object['sender']}")
sendToAgent(event_object)
return {
"_shsf": "v2",