Spaces:
Runtime error
Runtime error
| 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"] | |
| ) | |