Girishug's picture
Update main.py
a50fc00 verified
Raw
History Blame Contribute Delete
5.39 kB
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain.tools import Tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI
import yaml
import tempfile
import subprocess
import os
import shutil
import ast
from textwrap import indent
import re
import requests
# Local imports
from tools.read_file_tool import read_file
from tools.git_tool import scan_repository_structure, read_code_file
from tools.mcp_logger import log_mcp_entry
from langchain.agents import initialize_agent
from langchain.agents.agent_types import AgentType
# --- Load model config ---
def load_model_config(path="model_config.yaml"):
with open(path, "r") as f:
config = yaml.safe_load(f)
config["llm"]["api_key"] = os.environ.get("GROQ_API_KEY", "")
return config["llm"]
# --- Init Groq LLM ---
llm_config = load_model_config()
llm = ChatOpenAI(
model=llm_config["model"],
base_url=llm_config["base_url"],
api_key=llm_config["api_key"],
temperature=0.7
)
# --- Tools ---
def hello_world_tool(input: str) -> str:
return f"Hello, {input}! This is your agent speaking."
def smart_scan_repo(path_or_url: str) -> str:
if path_or_url.startswith("http"):
try:
temp_dir = tempfile.mkdtemp()
subprocess.run(["git", "clone", path_or_url, temp_dir], check=True, capture_output=True)
summary = scan_repository_structure(temp_dir)
shutil.rmtree(temp_dir)
return summary
except Exception as e:
return f"Error cloning remote repo: {e}"
else:
return scan_repository_structure(path_or_url)
def analyze_code_file(file_path: str) -> str:
try:
content = read_code_file(file_path)
analysis = f"### File Analysis: {file_path}\n"
analysis += f"- Lines: {len(content.splitlines())}\n"
if file_path.endswith(".py"):
try:
tree = ast.parse(content)
funcs = [node.name for node in ast.walk(tree) if isinstance(node, ast.FunctionDef)]
classes = [node.name for node in ast.walk(tree) if isinstance(node, ast.ClassDef)]
analysis += f"- Functions: {', '.join(funcs) or 'None'}\n"
analysis += f"- Classes: {', '.join(classes) or 'None'}\n"
except SyntaxError as e:
analysis += f"- ⚠️ Skipped AST parsing due to syntax error: {e}\n"
preview = content[:500].strip().replace("\n", "\n ")
analysis += f"\n### Sample Preview:\n {preview}...\n"
return analysis
except Exception as e:
return f"Error analyzing file: {e}"
tool_list = [
Tool(name="HelloTool", func=hello_world_tool, description="Sends a hello message."),
Tool(name="ReadFileTool", func=read_file, description="Reads a file content."),
Tool(name="SmartRepoScanner", func=smart_scan_repo, description="Scans a GitHub or local repo."),
Tool(name="AnalyzeCodeFile", func=analyze_code_file, description="Analyzes structure of a single code file."),
]
# --- Prompt + Agent Setup ---
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful AI assistant. Do not ask questions, just complete your task and return results."),
MessagesPlaceholder(variable_name="chat_history"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent_executor = initialize_agent(
tools=tool_list,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
return_intermediate_steps=True # <- Add this
)
# --- Utility Output Formatter ---
def pretty_print(output: str):
output = output.replace("**", "")
output = re.sub(r"\[(.*?)\]\((.*?)\)", r"\1: \2", output)
output = re.sub(r"```(.*?)```", r"\1", output, flags=re.DOTALL)
output = output.replace("* ", "- ")
print("\n" + indent(output.strip(), " ") + "\n")
# --- GitHub Repo Fetcher ---
def get_user_repos(username: str, limit: int = 3):
try:
url = f"https://api.github.com/users/{username}/repos"
response = requests.get(url)
response.raise_for_status()
repos = response.json()
return [repo["clone_url"] for repo in repos[:limit]]
except Exception:
return []
# --- Entry point for UI ---
def run_analysis(repo_url: str) -> str:
chat_history = []
response = agent_executor.invoke({
"input": f"Scan this Git repository: {repo_url}",
"chat_history": chat_history
})
return response["output"] if "output" in response else str(response)
# --- CLI Entry ---
if __name__ == "__main__":
chat_history = []
username = "GirishKGit"
repos = get_user_repos(username, limit=3)
for repo_url in repos:
print(f"\n🔍 Scanning Repository: {repo_url}\n")
user_input = f"Scan this Git repository: {repo_url}"
response = agent_executor.invoke({
"input": user_input,
"chat_history": chat_history
})
print("✅ Analysis Completed. Here's the Summary:")
pretty_print(response["output"])
log_mcp_entry(
agent_id="PolicyAgent",
user_query=user_input,
response=response["output"],
model_name=llm_config["model"],
base_url=llm_config["base_url"]
)