Skip to content

Commit 6b25854

Browse files
committed
Use a multi-agent approach
1 parent cf0a027 commit 6b25854

File tree

14 files changed

+501
-108
lines changed

14 files changed

+501
-108
lines changed

__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
"""CI Analysis coordinator: provide root cause analysis for CI failures"""
2+
13
from . import agent

agent.py

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,40 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""CI Analysis coordinator: provide root cause analysis for CI failures"""
16+
117
from google.adk.agents import LlmAgent
2-
from google.adk.models.lite_llm import LiteLlm
3-
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
18+
from google.adk.tools.agent_tool import AgentTool
19+
20+
from . import prompt
21+
from .sub_agents.installation_analyst import installation_analyst_agent
22+
from .sub_agents.mustgather_analyst import mustgather_analyst_agent
23+
MODEL = "gemini-2.0-flash"
424

525

6-
# TARGET_FOLDER_PATH = os.path.dirname(os.path.abspath(__file__))
7-
8-
root_agent = LlmAgent(
9-
name="root_agent_v1",
10-
# model="gemini-2.5-pro-preview-05-06",
11-
model="gemini-2.0-flash",
12-
# model=LiteLlm(model="ollama/qwen3:4b"),
13-
description="Provides analysis of CI jobs, and determines if the cluster installation was successful or not.",
14-
global_instruction="You are a helpful Kubernetes and Prow expert assistant. "
15-
"You are specialized in Openshift installation."
16-
"Your main goal is to analyze the Prow job's installation logs and diagnose possible failures of the cluster installation for the Prow job."
17-
"You provide root cause analysis for installation failures and propose solutions if possible."
18-
"You are truthful, concise, and helpful."
19-
"You never speculate about clusters being installed or fabricate information."
20-
"If you do not know the answer, you acknowledge the fact and end your response."
21-
"Your responses must be as short as possible."
22-
"CI JOB ANALYSIS WORKFLOW:"
23-
"-------------------------"
24-
"When analyzing a job failure, follow this recommended workflow:"
25-
"1. First, get a job's metadata (including test_name) and status by using 'get_job_metadata' tool."
26-
"2. Then, once you have the metadata, you can get install logs by using the 'get_install_logs' tool."
27-
"3. Check that the installation was successful by looking at the install logs."
28-
"4. Only if installation is successful, use 'get_build_logs' to get the job logs."
29-
"5. Analyze the job build logs to determine the root cause of the failure.",
30-
31-
tools=[
32-
MCPToolset(
33-
connection_params=StdioServerParameters(
34-
command='podman',
35-
args=["run", "-i", "-p", "9000:8000", "--rm", "-e", "MCP_TRANSPORT=stdio", "localhost/mcp-server-template:latest"],
36-
tool_filter=['get_build_logs','get_install_logs', 'get_job_metadata'],
37-
)
38-
),
39-
],
26+
ci_analysis_advisor = LlmAgent(
27+
name="ci_analysis_advisor",
28+
model=MODEL,
29+
description=(
30+
"Analyzes of CI jobs, and provide root cause analysis for failures."
31+
),
32+
instruction=prompt.CI_ANALYSIS_COORDINATOR_PROMPT,
33+
output_key="ci_analysis_advisor_output",
34+
tools=[
35+
AgentTool(agent=installation_analyst_agent),
36+
AgentTool(agent=mustgather_analyst_agent),
37+
],
4038
)
4139

40+
root_agent = ci_analysis_advisor

must_gather.py

Lines changed: 0 additions & 71 deletions
This file was deleted.

prompt.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
3+
"""Prompt for the ci_analysis_advisor_agent."""
4+
5+
CI_ANALYSIS_COORDINATOR_PROMPT = """
6+
Role: Act as a specialized Prow CI advisory assistant.
7+
8+
Overall Instructions for Interaction:
9+
10+
You are a helpful Kubernetes and Prow expert assistant.
11+
Your main goal is to analyze the Prow job and diagnose possible failures in the installation and tests performed by the Prow job.
12+
You provide root cause analysis for the failures and propose solutions if possible.
13+
You are truthful, concise, and helpful.
14+
You never speculate about clusters being installed or fabricate information.
15+
If you do not know the answer, you acknowledge the fact and end your response.
16+
Your responses must be as short as possible.
17+
CI JOB ANALYSIS WORKFLOW:
18+
-------------------------
19+
When analyzing a job failure, follow this recommended workflow:
20+
1. First, check that the installation was successful.
21+
2. Only if installation is successful, check the must-gather logs for more insights.
22+
23+
24+
At each step, clearly inform the user about the current subagent being called and the specific information required from them.
25+
After each subagent completes its task, explain the output provided and how it contributes to the overall root cause analysis process.
26+
Ensure all state keys are correctly used to pass information between subagents.
27+
Here's the step-by-step breakdown.
28+
For each step, explicitly call the designated subagent and adhere strictly to the specified input and output formats:
29+
30+
* Installation Analysis (Subagent: installation_analyst)
31+
32+
Input: Prompt the user to provide the link to the prow job they wish to analyze.
33+
Action: Parse the URL for the job_name and build_id. Call the installation_analyst subagent, passing the user-provided job_name and build_id.
34+
Expected Output: The installation_analyst subagent MUST return the job's job_name, build_id, test_name and a comprehensive data analysis for the installation of the cluster for the given job.
35+
36+
* Must_Gather Analysis (Subagent: mustgather_analyst)
37+
38+
Input: The installation_analysis_output from the installation_analyst subagent. Use /tmp/must-gather as the target_folder for the must-gather directory.
39+
Action: Call the mustgather_analyst subagent, passing the job_name, test_name and build_id. Download the must-gather logs: use /tmp/must-gather as the target_folder. Then analyze them by navigating the directory structure, reading files and searching for relevant information.
40+
Expected Output: The mustgather_analyst subagent MUST return a comprehensive data analysis for the execution of the given job.
41+
42+
"""

prow_mcp_server/mcp_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ async def get_install_logs(job_name: str, build_id: str, test_name: str):
174174
test_name: The name of the test for which to get install logs
175175
176176
Returns:
177-
Dictionary containing the installation logs or error information
177+
Dictionary containing the job metadata(job_name, build_id, test_name), installation logs or error information
178178
"""
179179
try:
180180
# Construct the artifacts URL
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .agent import installation_analyst_agent
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from google.adk import Agent
2+
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
3+
from . import prompt
4+
5+
MODEL = "gemini-2.0-flash"
6+
7+
8+
installation_analyst_agent = Agent(
9+
model=MODEL,
10+
name="installation_analyst_agent",
11+
instruction=prompt.INSTALLATION_SPECIALIST_PROMPT,
12+
output_key="installation_analysis_output",
13+
tools=[ MCPToolset(
14+
connection_params=StdioServerParameters(
15+
command='podman',
16+
args=["run", "-i", "-p", "9000:8000", "--rm", "-e", "MCP_TRANSPORT=stdio", "localhost/mcp-server-template:latest"],
17+
tool_filter=['get_install_logs', 'get_job_metadata'],
18+
)
19+
),
20+
],
21+
)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
INSTALLATION_SPECIALIST_PROMPT = """
2+
You are a helpful Kubernetes and Prow expert assistant.
3+
You are specialized in Openshift installation.
4+
Your main goal is to analyze the Prow job and diagnose possible failures in the installation and tests performed by the Prow job.
5+
You provide root cause analysis for the failures and propose solutions if possible.
6+
You are truthful, concise, and helpful.
7+
You never speculate about clusters being installed or fabricate information.
8+
If you do not know the answer, you acknowledge the fact and end your response.
9+
Your responses must be as short as possible.
10+
11+
First, get a job's metadata (including test_name) and status by using 'get_job_metadata' tool; you can get the build_id and the job_name from the URL provided by the user (resp. the last part of the URL and the before last part of the URL).
12+
Then, once you have the metadata, you can get install logs by using the 'get_install_logs' tool.
13+
Look for possible failures in the install logs.
14+
If you find any failures, provide a root cause analysis for the failures and propose solutions if possible.
15+
If you do not find any failures, say so.
16+
All your answers should contain the job_name, build_id and test_name.
17+
"""
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .agent import mustgather_analyst_agent
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from google.adk import Agent
2+
from . import prompt
3+
from .must_gather import get_must_gather, list_directory, read_drained_file, get_file_info, search_files
4+
MODEL = "gemini-2.0-flash"
5+
6+
mustgather_analyst_agent = Agent(
7+
model=MODEL,
8+
name="mustgather_analyst_agent",
9+
instruction=prompt.MUST_GATHER_SPECIALIST_PROMPT,
10+
output_key="must_gather_analysis_output",
11+
tools=[get_must_gather, list_directory, read_drained_file, get_file_info, search_files],
12+
)

0 commit comments

Comments
 (0)