Skip to content

Commit d8a258e

Browse files
committed
Add reporting in Jira about agent actions
Resolves: packit/jotnar#72 Signed-off-by: Siteshwar Vashisht <[email protected]>
1 parent afaa9df commit d8a258e

File tree

6 files changed

+89
-7
lines changed

6 files changed

+89
-7
lines changed

beeai/agents/backport_agent.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import asyncio
22
import logging
33
import os
4+
from shutil import rmtree
45
import subprocess
56
import sys
67
import traceback
8+
79
from pathlib import Path
810

911
from pydantic import BaseModel, Field
@@ -30,7 +32,7 @@
3032
from tools.text import CreateTool, InsertTool, StrReplaceTool, ViewTool
3133
from tools.wicked_git import GitLogSearchTool, GitPatchCreationTool
3234
from triage_agent import BackportData, ErrorData
33-
from utils import check_subprocess, get_agent_execution_config, mcp_tools, redis_client
35+
from utils import check_subprocess, get_agent_execution_config, mcp_tools, redis_client, post_private_jira_comment
3436

3537
logger = logging.getLogger(__name__)
3638

@@ -274,6 +276,19 @@ async def retry(task, error):
274276
logger.info(
275277
f"Backport processing completed for {backport_data.jira_issue}, " f"success: {state.backport_result.success}"
276278
)
279+
280+
agent_type = "Backport"
281+
if state.backport_result.success:
282+
logger.info(f"Updating JIRA {backport_data.jira_issue} with {state.backport_result.mr_url} ")
283+
284+
await post_private_jira_comment(gateway_tools, backport_data.jira_issue, agent_type, state.backport_result.mr_url)
285+
else:
286+
logger.info(f"Agent failed to perform a backport for {backport_data.jira_issue}.")
287+
await post_private_jira_comment(gateway_tools, backport_data.jira_issue, agent_type,
288+
"Agent failed to perform a backport: {state.backport_result.error}")
289+
290+
291+
277292
except Exception as e:
278293
error = "".join(traceback.format_exception(e))
279294
logger.error(f"Exception during backport processing for {backport_data.jira_issue}: {error}")

beeai/agents/constants.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
from string import Template
12

23
COMMIT_PREFIX = "[DO NOT MERGE: AI EXPERIMENTS]"
34

45
BRANCH_PREFIX = "automated-package-update"
6+
7+
AGENT_WARNING = "Warning: This is an AI-Generated contribution and may contain mistakes. Please carefully review the contributions made by AI agents."
8+
9+
JIRA_COMMENT_TEMPLATE = Template(f"""Output from $AGENT_TYPE Agent: $JIRA_COMMENT\n\n{AGENT_WARNING}""")

beeai/agents/rebase_agent.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from tools.specfile import AddChangelogEntryTool
2929
from tools.text import CreateTool, InsertTool, StrReplaceTool, ViewTool
3030
from triage_agent import RebaseData, ErrorData
31-
from utils import get_agent_execution_config, mcp_tools, redis_client, run_tool
31+
from utils import get_agent_execution_config, mcp_tools, redis_client, run_tool, post_private_jira_comment
3232

3333
logger = logging.getLogger(__name__)
3434

@@ -279,6 +279,16 @@ async def retry(task, error):
279279
logger.info(
280280
f"Rebase processing completed for {rebase_data.jira_issue}, " f"success: {state.rebase_result.success}"
281281
)
282+
283+
agent_type = "Rebase"
284+
if state.rebase_result.success:
285+
logger.info(f"Updating JIRA {rebase_data.jira_issue} with {state.rebase_result.mr_url} ")
286+
await post_private_jira_comment(gateway_tools, rebase_data.jira_issue, agent_type, state.rebase_result.mr_url)
287+
else:
288+
logger.info(f"Agent failed to perform a rebase for {rebase_data.jira_issue}.")
289+
await post_private_jira_comment(gateway_tools, rebase_data.jira_issue, agent_type,
290+
"Agent failed to perform a rebase: {state.rebase_result.error}")
291+
282292
except Exception as e:
283293
error = "".join(traceback.format_exception(e))
284294
logger.error(f"Exception during rebase processing for {rebase_data.jira_issue}: {error}")

beeai/agents/triage_agent.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from tools.commands import RunShellCommandTool
2525
from tools.patch_validator import PatchValidatorTool
2626
from tools.version_mapper import VersionMapperTool
27-
from utils import get_agent_execution_config, mcp_tools, redis_client
27+
from utils import get_agent_execution_config, mcp_tools, redis_client, post_private_jira_comment
2828

2929
logger = logging.getLogger(__name__)
3030

@@ -331,14 +331,20 @@ async def retry(task, error):
331331

332332
try:
333333
logger.info(f"Starting triage processing for {input.issue}")
334+
335+
# await post_private_jira_comment(gateway_tools, input.issue, "Starting ...")
336+
334337
output = await run(input)
335338
logger.info(
336339
f"Triage processing completed for {input.issue}, " f"resolution: {output.resolution.value}"
337340
)
338-
# tool = next(t for t in gateway_tools if t.name == "add_jira_comment")
339-
# await tool.run(input={"issue_key": input.issue, "comment": "..."}).middleware(
340-
# GlobalTrajectoryMiddleware(pretty=True)
341-
# )
341+
342+
agent_type = "Triage"
343+
if output.resolution.value == "clarification-needed":
344+
await post_private_jira_comment(gateway_tools, input.issue, agent_type, output.data.additional_info_needed)
345+
elif output.resolution.value == "no-action":
346+
await post_private_jira_comment(gateway_tools, input.issue, agent_type, output.data.reasoning)
347+
342348
except Exception as e:
343349
error = "".join(traceback.format_exception(e))
344350
logger.error(f"Exception during triage processing for {input.issue}: {error}")

beeai/agents/utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import logging
23
import os
34
import shlex
45
import subprocess
@@ -16,6 +17,7 @@
1617
from beeai_framework.tools import Tool
1718
from beeai_framework.tools.mcp import MCPTool
1819

20+
from constants import JIRA_COMMENT_TEMPLATE
1921

2022
def get_agent_execution_config() -> AgentExecutionConfig:
2123
return AgentExecutionConfig(
@@ -104,3 +106,25 @@ async def mcp_tools(
104106
if filter:
105107
tools = [t for t in tools if filter(t.name)]
106108
yield tools
109+
110+
async def post_private_jira_comment(gateway_tools: list, issue_key: str, agent_type: str, comment: str):
111+
"""Finds the Jira comment tool and posts a comment to the specified issue."""
112+
113+
logger = logging.getLogger(__name__)
114+
115+
dry_run = os.getenv("DRY_RUN", "False").lower() == "true"
116+
117+
if not dry_run:
118+
try:
119+
comment_tool = next(t for t in gateway_tools if t.name == "add_private_jira_comment")
120+
await comment_tool.run(
121+
input={
122+
"issue_key": issue_key,
123+
"comment": JIRA_COMMENT_TEMPLATE.substitute({"AGENT_TYPE": agent_type,
124+
"JIRA_COMMENT": comment}),
125+
}
126+
).middleware(GlobalTrajectoryMiddleware(pretty=True))
127+
except StopIteration:
128+
logger.error("Jira comment tool not found in gateway tools.")
129+
except Exception as e:
130+
logger.error(f"Failed to post Jira comment for issue {issue_key}: {e}")

beeai/mcp_server/jira_tools.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,25 @@ def add_jira_comment(
153153
except requests.RequestException as e:
154154
return f"Failed to add the specified comment: {e}"
155155
return f"Successfully added the specified comment to {issue_key}"
156+
157+
def add_private_jira_comment(
158+
issue_key: Annotated[str, Field(description="Jira issue key (e.g. RHEL-12345)")],
159+
comment: Annotated[str, Field(description="Comment text to add")],
160+
) -> str:
161+
"""
162+
Adds a private comment to the specified Jira issue.
163+
"""
164+
165+
if os.getenv("DRY_RUN", "False").lower() == "true":
166+
return "Dry run, not adding private comment"
167+
168+
try:
169+
response = requests.post(
170+
urljoin(os.getenv("JIRA_URL"), f"rest/api/2/issue/{issue_key}/comment"),
171+
json={"body": comment, "visibility": {"type":"group", "value":"Red Hat Employee"}},
172+
headers=_get_jira_headers(os.getenv("JIRA_TOKEN")),
173+
)
174+
response.raise_for_status()
175+
except requests.RequestException as e:
176+
return f"Failed to add the specified comment: {e}"
177+
return f"Successfully added the specified comment to {issue_key}"

0 commit comments

Comments
 (0)