Skip to content
Merged
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
18 changes: 17 additions & 1 deletion devops_agent/cli.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from pathlib import Path

import click
from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt
from devops_agent.core.master_agent import execute_master_agent
from devops_agent.core.log_analysis_agent import execute_log_analysis_agent

console = Console()

Expand Down Expand Up @@ -52,7 +55,20 @@ def run(log_file, provider, query, output, format, interactive):

if log_file:
console.print(f"[yellow]Analyzing log file:[/yellow] {log_file}")
console.print("[green]✓[/green] Log analysis will be implemented here")
try:
file_path = Path(__file__).parent.joinpath(log_file)
response = execute_log_analysis_agent(provider=provider, log_file=file_path)
console.print(Panel.fit(
f"[bold yellow]Assistant:[/bold yellow] [dim]{response}[/dim]",
border_style="yellow"
))

if output:
save_to_file(output, query, response, format)
console.print(f"\n[dim]Response saved to {output}[/dim]")

except Exception as e:
console.print(f"\n[red]Error:[/red] {str(e)}")

if query:
process_query(provider, query, output, format)
Expand Down
44 changes: 44 additions & 0 deletions devops_agent/core/log_analysis_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
from pathlib import Path

from agno.agent import Agent
from agno.media import File
from agno.models.openai import OpenAIChat
from agno.models.anthropic import Claude
from agno.models.google.gemini import Gemini
from rich.console import Console
from rich.panel import Panel

console = Console()

def execute_log_analysis_agent(provider: str, log_file: Path) -> Agent:
console.print(Panel.fit(
"[bold cyan]Log Analysis Agent Invoking...[/bold cyan]",
border_style="cyan"
))
llm_provider = provider.lower().strip()
if llm_provider == 'openai':
model = OpenAIChat(id="gpt-5-mini", api_key=os.environ.get('OPENAI_API_KEY'))
elif llm_provider == 'anthropic':
model = Claude(id="claude-sonnet-4-5-20250929", temperature=0.6, api_key=os.environ.get('ANTHROPIC_API_KEY'))
elif llm_provider == 'google':
model = Gemini(id="gemini-2.5-flash", temperature=0.6, api_key=os.environ.get('GEMINI_API_KEY'))
else:
model = OpenAIChat(id="gpt-5-mini"), #default

file_analysis_agent = Agent(
name="LogFile Analysis Agent",
role="Analyze log files",
model=model,
description="You are an AI agent that can analyze log files.",
instructions=[
"You are an AI agent that can analyze log files.",
"You are given a log file and you need to analyse and give detailed answer to the question from the user.",
],
)

print("executing the log analysis")
user_query = 'analyse and give all the insights such as critical errors, patterns, anomalies, or any other significant findings'
response = file_analysis_agent.run(user_query, files=[File(filepath=log_file)])

return response.content
14 changes: 6 additions & 8 deletions devops_agent/core/master_agent.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
import os
from pathlib import Path
from typing import Any

from agno.knowledge import Knowledge
Expand All @@ -16,12 +17,9 @@

from devops_agent.core.devops_agent import execute_devops_agent
from devops_agent.core.kubernetes_agent import execute_k8s_agent
from devops_agent.core.terraform_agent import execute_terraform_agent

from rich.console import Console
from rich.panel import Panel
from rich.live import Live
from rich.markdown import Markdown
from rich.console import Group

from dotenv import load_dotenv, find_dotenv

Expand All @@ -42,7 +40,7 @@
knowledge = Knowledge(vector_db=vector_db)


def execute_master_agent(provider: str, user_query: str) -> str:
def execute_master_agent(provider: str, user_query: str = None, log_file: Path = None) -> str:
llm_provider = provider.lower().strip()
if llm_provider == 'openai':
model = OpenAIChat(id="gpt-5-mini", api_key=os.environ.get('OPENAI_API_KEY'))
Expand All @@ -59,18 +57,19 @@ def execute_master_agent(provider: str, user_query: str) -> str:
members=[
execute_devops_agent(provider=provider),
execute_k8s_agent(provider=provider),
execute_terraform_agent(provider=provider)
],
instructions=[
"You are a intelligent router that directs questions to the appropriate agent.",
"If the user asks in a non devops or k8s question whose agent is not a team member, respond in English with:",
"'I can only answer in the following technologies: Devops & Kubernetes Architecture on Multiple clouds. Please ask your question in one of these technologies.'",
"'I can only answer in the following technologies: Devops, terraform & Kubernetes Architecture on Multiple clouds. Please ask your question in one of these technologies.'",
"Always check the technology or domain of the user's input before routing to an agent.",
"For unsupported technologies like coding, flowcharts, analytics etc respond in English with the above message.",
],
tools=[ReasoningTools()], # Enable reasoning capabilities
knowledge=knowledge,
db=InMemoryDb(),
respond_directly=False, # if set to true the member response if directly given to user
respond_directly=True, # if set to true the member response is directly given to user
determine_input_for_members=False,
delegate_task_to_all_members=False,
stream_intermediate_steps=True,
Expand All @@ -82,7 +81,6 @@ def execute_master_agent(provider: str, user_query: str) -> str:
enable_agentic_memory=True,
markdown=True
)

response = devops_team.run(user_query, stream_intermediate_steps=True, retry=3)

# saved the response to knowledge in async mode
Expand Down
43 changes: 43 additions & 0 deletions devops_agent/core/terraform_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import asyncio
import os

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.models.anthropic import Claude
from agno.models.google.gemini import Gemini
from rich.console import Console
from rich.panel import Panel

from devops_agent.utils.prompt_generator_from_poml import prompt_from_poml

terraform_prompt = prompt_from_poml('terraform.poml')

console = Console()

def execute_terraform_agent(provider: str, user_query: str = None) -> Agent:

console.print(Panel.fit(
"[bold cyan]Terraform Agent Invoking...[/bold cyan]",
border_style="cyan"
))

llm_provider = provider.lower().strip()
if llm_provider == 'openai':
model = OpenAIChat(id="gpt-5-mini", api_key=os.environ.get('OPENAI_API_KEY'))
elif llm_provider == 'anthropic':
model = Claude(id="claude-sonnet-4-5-20250929", temperature=0.6, api_key=os.environ.get('ANTHROPIC_API_KEY'))
elif llm_provider == 'google':
model = Gemini(id="gemini-2.5-flash", temperature=0.6, api_key=os.environ.get('GEMINI_API_KEY'))
else:
model = OpenAIChat(id="gpt-5-mini"), # default

terraform_assist = Agent(
name="Kubernetes Agent",
model=model,
description="You help answer questions about the terraform technology with respect to platforms like Azure, AWS, and GCP. Always ask the cloud provider if not provided in the user_query before proceeding.",
instructions=terraform_prompt,
stream_intermediate_steps=True,
markdown=True,
)

return terraform_assist
7 changes: 0 additions & 7 deletions devops_agent/playground.py

This file was deleted.