Skip to content

Commit 55131ea

Browse files
committed
inject prompt if jira tool is detected
1 parent 3b32d85 commit 55131ea

File tree

4 files changed

+64
-39
lines changed

4 files changed

+64
-39
lines changed

bugzooka/analysis/prompts.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,13 @@
5151
),
5252
"assistant": "Here is a context-aware analysis of the most relevant failures:",
5353
}
54+
55+
# Jira tool prompt - used when Jira MCP tools are available
56+
JIRA_TOOL_PROMPT = {
57+
"system_suffix": (
58+
"\n\nIMPORTANT: You have access to JIRA search tools. After analyzing the error, "
59+
"ALWAYS search for related issues in JIRA using the search_jira_issues tool with the OCPBUGS project. "
60+
"Extract key error terms, component names, or operators from the log summary to search for similar issues. "
61+
"Include the top 3 most relevant JIRA issues in your final response under a 'Related JIRA Issues' section."
62+
),
63+
}

bugzooka/integrations/gemini_client.py

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import ssl
44
import httpx
55
import json
6-
import asyncio
76

87
from openai import OpenAI
98
from langchain_core.utils.function_calling import convert_to_openai_tool
@@ -13,6 +12,7 @@
1312
INFERENCE_MAX_TOOL_ITERATIONS,
1413
)
1514
from bugzooka.integrations.inference import InferenceAPIUnavailableError
15+
from bugzooka.analysis.prompts import JIRA_TOOL_PROMPT
1616

1717

1818
logger = logging.getLogger(__name__)
@@ -127,10 +127,10 @@ async def execute_tool_call(tool_name, tool_args, available_tools):
127127
logger.info("Executing tool: %s with args: %s", tool_name, tool_args)
128128

129129
# Check if the tool is async (has coroutine attribute or ainvoke method)
130-
if hasattr(tool, 'coroutine') and tool.coroutine:
130+
if hasattr(tool, "coroutine") and tool.coroutine:
131131
# MCP tools have a coroutine attribute
132132
result = await tool.ainvoke(tool_args)
133-
elif hasattr(tool, 'ainvoke'):
133+
elif hasattr(tool, "ainvoke"):
134134
# Some tools have ainvoke method
135135
result = await tool.ainvoke(tool_args)
136136
else:
@@ -151,7 +151,7 @@ async def analyze_log_with_gemini(
151151
error_summary: str,
152152
model="gemini-2.0-flash",
153153
tools=None,
154-
max_iterations=None
154+
max_iterations=None,
155155
):
156156
"""
157157
Analyzes log summaries using Gemini API with product-specific prompts and optional tool calling.
@@ -171,6 +171,17 @@ async def analyze_log_with_gemini(
171171
gemini_client = GeminiClient()
172172

173173
prompt_config = product_config["prompt"][product]
174+
175+
# Check if Jira MCP tools are available and inject Jira prompt
176+
has_jira = tools and any(
177+
hasattr(t, "name") and t.name == "search_jira_issues" for t in tools
178+
)
179+
if has_jira:
180+
logger.info("Jira MCP tools detected - injecting Jira prompt")
181+
system_prompt = prompt_config["system"] + JIRA_TOOL_PROMPT["system_suffix"]
182+
else:
183+
system_prompt = prompt_config["system"]
184+
174185
try:
175186
formatted_content = prompt_config["user"].format(
176187
error_summary=error_summary
@@ -179,7 +190,7 @@ async def analyze_log_with_gemini(
179190
formatted_content = prompt_config["user"].format(summary=error_summary)
180191

181192
messages = [
182-
{"role": "system", "content": prompt_config["system"]},
193+
{"role": "system", "content": system_prompt},
183194
{"role": "user", "content": formatted_content},
184195
{"role": "assistant", "content": prompt_config["assistant"]},
185196
]
@@ -188,9 +199,11 @@ async def analyze_log_with_gemini(
188199
openai_tools = None
189200
if tools:
190201
openai_tools = convert_langchain_tools_to_openai_format(tools)
191-
logger.info("Enabled %d tools for Gemini: %s",
192-
len(openai_tools),
193-
[t["function"]["name"] for t in openai_tools])
202+
logger.info(
203+
"Enabled %d tools for Gemini: %s",
204+
len(openai_tools),
205+
[t["function"]["name"] for t in openai_tools],
206+
)
194207

195208
# Tool calling loop - iterate until we get a final answer or hit max iterations
196209
iteration = 0
@@ -214,7 +227,7 @@ async def analyze_log_with_gemini(
214227
response_message = response.choices[0].message
215228

216229
# Check if Gemini wants to call tools
217-
tool_calls = getattr(response_message, 'tool_calls', None)
230+
tool_calls = getattr(response_message, "tool_calls", None)
218231

219232
if not tool_calls:
220233
# No tool calls - we have the final answer
@@ -229,21 +242,23 @@ async def analyze_log_with_gemini(
229242
logger.info("Gemini requested %d tool call(s)", len(tool_calls))
230243

231244
# Add the assistant's message with tool calls to conversation
232-
messages.append({
233-
"role": "assistant",
234-
"content": response_message.content or "",
235-
"tool_calls": [
236-
{
237-
"id": tc.id,
238-
"type": "function",
239-
"function": {
240-
"name": tc.function.name,
241-
"arguments": tc.function.arguments
245+
messages.append(
246+
{
247+
"role": "assistant",
248+
"content": response_message.content or "",
249+
"tool_calls": [
250+
{
251+
"id": tc.id,
252+
"type": "function",
253+
"function": {
254+
"name": tc.function.name,
255+
"arguments": tc.function.arguments,
256+
},
242257
}
243-
}
244-
for tc in tool_calls
245-
]
246-
})
258+
for tc in tool_calls
259+
],
260+
}
261+
)
247262

248263
# Execute each tool call and add results to messages
249264
for tool_call in tool_calls:
@@ -256,25 +271,25 @@ async def analyze_log_with_gemini(
256271
else:
257272
# Execute the tool (await since it's now async)
258273
function_result = await execute_tool_call(
259-
function_name,
260-
function_args,
261-
tools
274+
function_name, function_args, tools
262275
)
263276

264277
# Add tool result to messages
265-
messages.append({
266-
"role": "tool",
267-
"tool_call_id": tool_call.id,
268-
"name": function_name,
269-
"content": function_result
270-
})
278+
messages.append(
279+
{
280+
"role": "tool",
281+
"tool_call_id": tool_call.id,
282+
"name": function_name,
283+
"content": function_result,
284+
}
285+
)
271286

272287
# Continue loop to let Gemini process tool results
273288

274289
# If we hit max iterations without a final answer
275290
logger.warning(
276291
"Reached maximum tool calling iterations (%d) without final answer",
277-
max_iterations
292+
max_iterations,
278293
)
279294
return "Analysis incomplete: Maximum tool calling iterations reached. Please try again with a simpler query."
280295

kustomize/base/configmap-prompts.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ data:
99
prompts.json: |
1010
{
1111
"OPENSHIFT_PROMPT": {
12-
"system": "You are an expert in OpenShift, Kubernetes, and cloud infrastructure. Your task is to analyze logs and summaries related to OpenShift environments. Given a log summary, identify the root cause, potential fixes, and affected components. Be as consise as possible (under 5000 characters), but precise and avoid generic troubleshooting steps. Prioritize OpenShift-specific debugging techniques. Keep in mind that the cluster is ephemeral and is destroyed after the build is complete, but all relevant logs and metrics are available. Use markdown formatting for the output with only one level of bullet points, do not use bold text except for the headers.\n\nIMPORTANT: You have access to JIRA search tools. After analyzing the error, ALWAYS search for related issues in JIRA using the search_jira_issues tool with the OCPBUGS project. Extract key error terms, component names, or operators from the log summary to search for similar issues. Include the top 3 most relevant JIRA issues in your final response under a 'Related JIRA Issues' section.",
13-
"user": "Here is the log summary from an OpenShift environment:\n\n{summary}\n\nBased on this summary, provide a structured breakdown of:\n- The OpenShift component likely affected (e.g., etcd, kube-apiserver, ingress, SDN, Machine API)\n- The probable root cause\n- Steps to verify the issue further\n- Suggested resolution, including OpenShift-specific commands or configurations\n- Related JIRA issues (search using search_jira_issues tool with OCPBUGS project and include the top 3 most relevant issues)",
14-
"assistant": "**Affected Component:** <Identified component>\n\n**Probable Root Cause:** <Describe why this issue might be occurring>\n\n**Verification Steps:**\n- <Step 1>\n- <Step 2>\n- <Step 3>\n\n**Suggested Resolution:**\n- <OpenShift CLI commands>\n- <Relevant OpenShift configurations>\n\n**Related JIRA Issues:**\n- <Top 3 relevant issues from JIRA search>"
12+
"system": "You are an expert in OpenShift, Kubernetes, and cloud infrastructure. Your task is to analyze logs and summaries related to OpenShift environments. Given a log summary, identify the root cause, potential fixes, and affected components. Be as consise as possible (under 5000 characters), but precise and avoid generic troubleshooting steps. Prioritize OpenShift-specific debugging techniques. Keep in mind that the cluster is ephemeral and is destroyed after the build is complete, but all relevant logs and metrics are available. Use markdown formatting for the output with only one level of bullet points, do not use bold text except for the headers.",
13+
"user": "Here is the log summary from an OpenShift environment:\n\n{summary}\n\nBased on this summary, provide a structured breakdown of:\n- The OpenShift component likely affected (e.g., etcd, kube-apiserver, ingress, SDN, Machine API)\n- The probable root cause\n- Steps to verify the issue further\n- Suggested resolution, including OpenShift-specific commands or configurations",
14+
"assistant": "**Affected Component:** <Identified component>\n\n**Probable Root Cause:** <Describe why this issue might be occurring>\n\n**Verification Steps:**\n- <Step 1>\n- <Step 2>\n- <Step 3>\n\n**Suggested Resolution:**\n- <OpenShift CLI commands>\n- <Relevant OpenShift configurations>"
1515
},
1616
"ANSIBLE_PROMPT": {
1717
"system": "You are an expert in Ansible automation, playbook debugging, and infrastructure as code (IaC). Your task is to analyze log summaries related to Ansible execution, playbook failures, and task errors. Given a log summary, identify the root cause, affected tasks, and potential fixes. Prioritize Ansible-specific debugging techniques over generic troubleshooting.",

prompts.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"OPENSHIFT_PROMPT": {
3-
"system": "You are an expert in OpenShift, Kubernetes, and cloud infrastructure. Your task is to analyze logs and summaries related to OpenShift environments. Given a log summary, identify the root cause, potential fixes, and affected components. Be as consise as possible (under 5000 characters), but precise and avoid generic troubleshooting steps. Prioritize OpenShift-specific debugging techniques. Keep in mind that the cluster is ephemeral and is destroyed after the build is complete, but all relevant logs and metrics are available. Use markdown formatting for the output with only one level of bullet points, do not use bold text except for the headers.\n\nIMPORTANT: You have access to JIRA search tools. After analyzing the error, ALWAYS search for related issues in JIRA using the search_jira_issues tool with the OCPBUGS project. Extract key error terms, component names, or operators from the log summary to search for similar issues. Include the top 3 most relevant JIRA issues in your final response under a 'Related JIRA Issues' section.",
4-
"user": "Here is the log summary from an OpenShift environment:\n\n{summary}\n\nBased on this summary, provide a structured breakdown of:\n- The OpenShift component likely affected (e.g., etcd, kube-apiserver, ingress, SDN, Machine API)\n- The probable root cause\n- Steps to verify the issue further\n- Suggested resolution, including OpenShift-specific commands or configurations\n- Related JIRA issues (search using search_jira_issues tool with OCPBUGS project and include the top 3 most relevant issues)",
5-
"assistant": "**Affected Component:** <Identified component>\n\n**Probable Root Cause:** <Describe why this issue might be occurring>\n\n**Verification Steps:**\n- <Step 1>\n- <Step 2>\n- <Step 3>\n\n**Suggested Resolution:**\n- <OpenShift CLI commands>\n- <Relevant OpenShift configurations>\n\n**Related JIRA Issues:**\n- <Top 3 relevant issues from JIRA search>"
3+
"system": "You are an expert in OpenShift, Kubernetes, and cloud infrastructure. Your task is to analyze logs and summaries related to OpenShift environments. Given a log summary, identify the root cause, potential fixes, and affected components. Be as consise as possible (under 5000 characters), but precise and avoid generic troubleshooting steps. Prioritize OpenShift-specific debugging techniques. Keep in mind that the cluster is ephemeral and is destroyed after the build is complete, but all relevant logs and metrics are available. Use markdown formatting for the output with only one level of bullet points, do not use bold text except for the headers.",
4+
"user": "Here is the log summary from an OpenShift environment:\n\n{summary}\n\nBased on this summary, provide a structured breakdown of:\n- The OpenShift component likely affected (e.g., etcd, kube-apiserver, ingress, SDN, Machine API)\n- The probable root cause\n- Steps to verify the issue further\n- Suggested resolution, including OpenShift-specific commands or configurations",
5+
"assistant": "**Affected Component:** <Identified component>\n\n**Probable Root Cause:** <Describe why this issue might be occurring>\n\n**Verification Steps:**\n- <Step 1>\n- <Step 2>\n- <Step 3>\n\n**Suggested Resolution:**\n- <OpenShift CLI commands>\n- <Relevant OpenShift configurations>"
66
},
77
"ANSIBLE_PROMPT": {
88
"system": "You are an expert in Ansible automation, playbook debugging, and infrastructure as code (IaC). Your task is to analyze log summaries related to Ansible execution, playbook failures, and task errors. Given a log summary, identify the root cause, affected tasks, and potential fixes. Prioritize Ansible-specific debugging techniques over generic troubleshooting.",

0 commit comments

Comments
 (0)