DeepActionPotential commited on
Commit
5249394
·
verified ·
1 Parent(s): a11b14f

Upload folder using huggingface_hub

Browse files
LICENCE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Eslam Tarek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
__pycache__/config.cpython-311.pyc ADDED
Binary file (3.41 kB). View file
 
agents/__pycache__/agents.cpython-311.pyc ADDED
Binary file (850 Bytes). View file
 
agents/__pycache__/code_overview_agents.cpython-311.pyc ADDED
Binary file (5.04 kB). View file
 
agents/__pycache__/code_structure_agents.cpython-311.pyc ADDED
Binary file (6.13 kB). View file
 
agents/__pycache__/code_visualization_agents.cpython-311.pyc ADDED
Binary file (1.93 kB). View file
 
agents/__pycache__/directory_manager.cpython-311.pyc ADDED
Binary file (2.87 kB). View file
 
agents/__pycache__/manager_agent.cpython-311.pyc ADDED
Binary file (3.59 kB). View file
 
agents/code_overview_agents.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+ from autogen import ConversableAgent, UserProxyAgent, AssistantAgent
5
+ from typing import Dict, Any
6
+
7
+
8
+ class CodeSummarizerAgent:
9
+ name: str = 'CodeSummarizerAgent'
10
+ system_message: str = """
11
+
12
+ You are an expert software engineer and technical writer.
13
+
14
+ Your job is to analyze the code provided to you and produce:
15
+ 1. A high-level summary of what the code is doing.
16
+ 2. An explanation of any major classes, functions, and logic flow.
17
+ 3. The purpose of the code (what task it's solving).
18
+ 4. Any helpful notes about the code structure or style, if relevant.
19
+
20
+ Your goal is to make the code understandable to a junior developer or a non-expert.
21
+ Keep the explanation concise, clear, and helpful.
22
+
23
+
24
+ """
25
+ code_execution_config: bool = False
26
+ human_input_mode: str = "NEVER"
27
+
28
+ def to_dict(self):
29
+ return {
30
+ "name": self.name,
31
+ "system_message": self.system_message,
32
+ "code_execution_config": self.code_execution_config,
33
+ "human_input_mode": self.human_input_mode
34
+ }
35
+
36
+ def make_agent(self, llm_config:Dict[str, Any]) -> ConversableAgent:
37
+ return ConversableAgent(**self.to_dict(), llm_config=llm_config)
38
+
39
+
40
+
41
+
42
+ class CodeSmellDetectorAgent:
43
+ name: str = 'CodeSmellDetectorAgent'
44
+ system_message: str = """
45
+ You are an expert software engineer and code quality reviewer.
46
+
47
+ Your task is to detect code smells in the provided source code.
48
+ You should:
49
+ 1. Identify common code smells such as:
50
+ - Long methods/functions
51
+ - God objects (classes doing too much)
52
+ - Deep nesting
53
+ - Duplicate code
54
+ - Poor naming conventions
55
+ - Too many parameters
56
+ - Magic numbers or hardcoded values
57
+ - Violations of the Single Responsibility Principle
58
+ 2. Explain why each code smell is problematic.
59
+ 3. Suggest specific refactoring strategies to improve the code quality.
60
+ 4. Optionally, evaluate how severe the smell is (low, medium, high impact).
61
+
62
+ Present your findings clearly and helpfully as if you're mentoring a junior developer.
63
+ Do not rewrite the code unless asked to. Focus on code critique and reasoning.
64
+ """
65
+ code_execution_config: bool = False
66
+ human_input_mode: str = "NEVER"
67
+
68
+ def to_dict(self):
69
+ return {
70
+ "name": self.name,
71
+ "system_message": self.system_message,
72
+ "code_execution_config": self.code_execution_config,
73
+ "human_input_mode": self.human_input_mode
74
+ }
75
+
76
+ def make_agent(self, llm_config: Dict[str, Any]) -> ConversableAgent:
77
+ return ConversableAgent(**self.to_dict(), llm_config=llm_config)
78
+
79
+
80
+
81
+
82
+ class ComplexityAnalyzerAgent:
83
+ name: str = "ComplexityAnalyzerAgent"
84
+ system_message: str = """
85
+ You are an expert software performance engineer and static code analyzer.
86
+
87
+ Your job is to analyze the complexity of the given code file. Focus on:
88
+ 1. Cyclomatic complexity of each function.
89
+ 2. Deeply nested conditionals or loops.
90
+ 3. Long functions or classes that might be doing too much.
91
+ 4. Recommendations for breaking down complex parts.
92
+
93
+ Provide a complexity score or risk level for each main function and class.
94
+ Your output should be formatted and readable for engineers reviewing the code quality.
95
+ """
96
+ code_execution_config: bool = False
97
+ human_input_mode: str = "NEVER"
98
+
99
+ def to_dict(self):
100
+ return {
101
+ "name": self.name,
102
+ "system_message": self.system_message,
103
+ "code_execution_config": self.code_execution_config,
104
+ "human_input_mode": self.human_input_mode
105
+ }
106
+
107
+ def make_agent(self, llm_config: Dict[str, Any]) -> ConversableAgent :
108
+ return ConversableAgent(**self.to_dict(), llm_config=llm_config)
agents/code_structure_agents.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from typing import Dict, Any
3
+ from autogen import ConversableAgent
4
+
5
+
6
+
7
+
8
+
9
+ class DesignPatternDetectorAgent:
10
+ name: str = 'DesignPatternDetectorAgent'
11
+ system_message: str = """
12
+ You are an expert software architect and design pattern specialist.
13
+
14
+ Your job is to analyze the code provided to you and determine whether any known software design patterns are applied.
15
+ You should:
16
+
17
+ 1. Identify common design patterns used in the code (e.g., Singleton, Factory, Observer, Strategy, Adapter, etc.).
18
+ 2. Explain where and how each pattern is used (e.g., "This class behaves like a Singleton because...").
19
+ 3. Evaluate whether the pattern is applied correctly and effectively.
20
+ 4. Suggest a design pattern if none are found but the situation could benefit from one.
21
+ 5. Be specific and concise. Include references to classes/functions when possible.
22
+
23
+ Your goal is to help developers understand the architectural design decisions in the codebase and encourage good pattern usage.
24
+ """
25
+ code_execution_config: bool = False
26
+ human_input_mode: str = "NEVER"
27
+
28
+ def to_dict(self):
29
+ return {
30
+ "name": self.name,
31
+ "system_message": self.system_message,
32
+ "code_execution_config": self.code_execution_config,
33
+ "human_input_mode": self.human_input_mode
34
+ }
35
+
36
+ def make_agent(self, llm_config: Dict[str, Any]) -> ConversableAgent:
37
+ return ConversableAgent(**self.to_dict(), llm_config=llm_config)
38
+
39
+
40
+
41
+ class DesignPatternRecommenderAgent:
42
+ name: str = 'DesignPatternRecommenderAgent'
43
+ system_message: str = """
44
+ You are a senior software architect and design pattern expert.
45
+
46
+ Your task is to analyze the provided source code and recommend suitable design patterns that could be applied to improve its structure, flexibility, and maintainability.
47
+
48
+ You should:
49
+ 1. Detect parts of the code that would benefit from design patterns (e.g., duplicated logic, tight coupling, hard-coded logic, lack of abstraction).
50
+ 2. Recommend one or more appropriate design patterns (e.g., Strategy, Factory, Adapter, Singleton, Observer, etc.).
51
+ 3. Explain **why** each recommended pattern fits the situation, including the benefits it provides.
52
+ 4. Mention **how** the developer can refactor or restructure the code to apply the suggested pattern (briefly).
53
+ 5. Keep your explanation clear and actionable for an intermediate-level developer.
54
+
55
+ Your goal is to guide developers toward more scalable and clean software design using well-known object-oriented design patterns.
56
+ """
57
+ code_execution_config: bool = False
58
+ human_input_mode: str = "NEVER"
59
+
60
+ def to_dict(self):
61
+ return {
62
+ "name": self.name,
63
+ "system_message": self.system_message,
64
+ "code_execution_config": self.code_execution_config,
65
+ "human_input_mode": self.human_input_mode
66
+ }
67
+
68
+ def make_agent(self, llm_config: Dict[str, Any]) -> ConversableAgent:
69
+ return ConversableAgent(**self.to_dict(), llm_config=llm_config)
70
+
71
+
72
+
73
+
74
+ class SOLIDPrinciplesManagerAgent:
75
+ name: str = 'SOLIDPrinciplesManagerAgent'
76
+ system_message: str = """
77
+ You are a senior software architect and expert in object-oriented design and clean code principles.
78
+
79
+ Your job is to analyze the provided code and manage its compliance with the SOLID principles. The SOLID principles are:
80
+
81
+ 1. **Single Responsibility Principle (SRP)** – each class should have one responsibility.
82
+ 2. **Open/Closed Principle (OCP)** – software entities should be open for extension but closed for modification.
83
+ 3. **Liskov Substitution Principle (LSP)** – subclasses should be replaceable for their base classes without altering functionality.
84
+ 4. **Interface Segregation Principle (ISP)** – interfaces should be specific to client needs.
85
+ 5. **Dependency Inversion Principle (DIP)** – high-level modules should not depend on low-level modules; both should depend on abstractions.
86
+
87
+ You should:
88
+ 1. Identify whether each principle is being followed or violated.
89
+ 2. Provide clear feedback on each principle's presence or absence.
90
+ 3. Recommend specific improvements where the code violates any SOLID principle.
91
+ 4. Explain why the principle matters and how to refactor or redesign the code accordingly.
92
+ 5. Be concise, clear, and educational.
93
+
94
+ The goal is to help developers build maintainable, scalable, and clean object-oriented software.
95
+ """
96
+ code_execution_config: bool = False
97
+ human_input_mode: str = "NEVER"
98
+
99
+ def to_dict(self):
100
+ return {
101
+ "name": self.name,
102
+ "system_message": self.system_message,
103
+ "code_execution_config": self.code_execution_config,
104
+ "human_input_mode": self.human_input_mode
105
+ }
106
+
107
+ def make_agent(self, llm_config: Dict[str, Any]) -> ConversableAgent:
108
+ return ConversableAgent(**self.to_dict(), llm_config=llm_config)
109
+
110
+
111
+
agents/code_visualization_agents.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ from autogen import ConversableAgent
4
+ from typing import Dict, Any
5
+
6
+ class MermaideDiagramAgent:
7
+ name: str = "MermaideDiagramAgent"
8
+ system_message: str = """
9
+ You are an expert software architect.
10
+
11
+ Your task is to read a given code file and generate a visual architecture diagram using Mermaid.js syntax.
12
+ Focus on:
13
+ 1. High-level modules and packages.
14
+ 2. Class and function relationships (inheritance, calls).
15
+ 3. Imports and module-level structure.
16
+
17
+ Output should be concise, visual, and suitable for developers to understand overall code architecture quickly.
18
+ Only output the Mermaid.js code block, nothing else.
19
+ """
20
+ code_execution_config: bool = False
21
+ human_input_mode: str = "NEVER"
22
+
23
+ def to_dict(self):
24
+ return {
25
+ "name": self.name,
26
+ "system_message": self.system_message,
27
+ "code_execution_config": self.code_execution_config,
28
+ "human_input_mode": self.human_input_mode
29
+ }
30
+
31
+ def make_agent(self, llm_config: Dict[str, Any]) -> ConversableAgent:
32
+ return ConversableAgent(**self.to_dict(), llm_config=llm_config)
agents/directory_agents.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, Any
2
+ from autogen import AssistantAgent
3
+
4
+ from services.utils import get_directory_tree
5
+
6
+ class DirectoryManagerAgent:
7
+ """
8
+ An assistant agent designed to inspect and analyze project directory structures.
9
+
10
+ Your job is to:
11
+ 1. Fetch and present the directory tree of a given path.
12
+ 2. Identify the structure of codebases.
13
+ 3. Suggest which folders might contain main modules, tests, configs, documentation, etc.
14
+ 4. Help other agents decide what to analyze next based on the file layout.
15
+
16
+ at the end of your response, show used python tools from my enviroment "functions"
17
+ """
18
+
19
+ name: str = 'DirectoryManagerAgent'
20
+ system_message: str = """
21
+
22
+ An assistant agent designed to inspect and analyze project directory structures.
23
+
24
+ Your job is to:
25
+ 1. Fetch and present the directory tree of a given path.
26
+ 2. Identify the structure of codebases.
27
+ 3. Suggest which folders might contain main modules, tests, configs, documentation, etc.
28
+ 4. Help other agents decide what to analyze next based on the file layout.
29
+
30
+
31
+ """
32
+ human_input_mode: str = "NEVER"
33
+
34
+
35
+ def to_dict(self) -> Dict[str, Any]:
36
+ """Convert agent configuration to a dictionary"""
37
+ return {
38
+ "name": self.name,
39
+ "system_message": self.system_message,
40
+ "human_input_mode": self.human_input_mode,
41
+ }
42
+
43
+
44
+ def _store_function_tools(self) -> None:
45
+ """Set the list of function tools for the agent"""
46
+ self.tools = [
47
+ {
48
+ "type": "function",
49
+ "function": {
50
+ "name": "get_directory_tree",
51
+ "description": "Get directory tree structure starting from specified path, excluding certain folders",
52
+ "parameters": {
53
+ "type": "object",
54
+ "properties": {
55
+ "path": {
56
+ "type": "string",
57
+ "description": "Directory path to start from (e.g., '.' for current directory)"
58
+ },
59
+ "indent": {
60
+ "type": "string",
61
+ "description": "Indentation string for formatting",
62
+ "default": ""
63
+ },
64
+ "exclude_folder": {
65
+ "type": "string",
66
+ "description": "Folder name to exclude from the tree",
67
+ "default": "__pycache__"
68
+ }
69
+ },
70
+ "required": ["path"]
71
+ }
72
+ }
73
+ }
74
+ ]
75
+
76
+
77
+ def _add_agents_tools_to_config(self, llm_config:Dict[str, Any]) -> None:
78
+ """Add the tools to the llm_config"""
79
+ llm_config["tools"] = self.tools
80
+ return llm_config
81
+
82
+ def make_agent(self, llm_config: Dict[str, Any]) -> AssistantAgent:
83
+ """Create an instance of the agent with the given configuration"""
84
+ self._store_function_tools()
85
+ self.llm_config = self._add_agents_tools_to_config(llm_config)
86
+
87
+ return AssistantAgent(
88
+ **self.to_dict(),
89
+ llm_config=self.llm_config,
90
+ code_execution_config={"work_dir": ".", 'use_docker': False},
91
+ function_map={
92
+ "get_directory_tree": get_directory_tree
93
+ }
94
+ )
agents/manager_agent.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, Any
2
+ from autogen import ConversableAgent, UserProxyAgent
3
+
4
+ class ManagerAgent:
5
+ name: str = 'ManagerAgent'
6
+ system_message: str = """
7
+ You are a Manager Agent responsible for overseeing and orchestrating a team of specialized code analysis agents. Your team includes:
8
+
9
+ - **CodeSummarizerAgent:** Provides a high-level summary of the code including an explanation of major classes, functions, and overall logic.
10
+ - **CodeSmellDetectorAgent:** Detects potential code smells (e.g., long methods, God objects, deep nesting, etc.), explains why they are problematic, and suggests refactoring strategies.
11
+ - **DesignPatternDetectorAgent:** Identifies commonly used design patterns within the code and explains how they are applied.
12
+ - **DesignPatternRecommenderAgent:** Evaluates the code and recommends suitable design patterns to improve structure, flexibility, and maintainability.
13
+ - **SOLIDPrinciplesManagerAgent:** Analyzes code compliance with the SOLID principles and provides actionable feedback for enhancing code quality.
14
+ - **DirectoryManagerAgent:** manages code directory structure and helps in navigating the codebase.
15
+
16
+ Your responsibilities are:
17
+ 1. **Assess Incoming Requests:** Analyze the provided code or query and decide which specialized agent(s) should handle each aspect of the analysis.
18
+ 2. **Delegate Tasks:** Route parts of the code analysis to the appropriate agent based on the needs of the request.
19
+ 3. **Aggregate Responses:** Collect and synthesize the outputs from the various agents into a cohesive, clear, and structured report.
20
+ 4. **Ensure Clarity and Consistency:** Present the final analysis in a manner that is both understandable to junior developers and valuable to experienced engineers.
21
+ 5. **Maintain Best Practices:** Ensure that all insights and recommendations adhere to best practices in software engineering, architecture, and clean code principles.
22
+
23
+ Your goal is to streamline the code review process by ensuring that each specialized agent contributes effectively, and by delivering a final, comprehensive analysis that covers high-level summaries, code smells, design patterns, and SOLID principles. Work as the central coordinator to enhance the clarity and quality of the overall feedback provided to the developers.
24
+ """
25
+ code_execution_config: bool = False
26
+ human_input_mode: str = "NEVER"
27
+
28
+ def to_dict(self) -> Dict[str, Any]:
29
+ return {
30
+ "name": self.name,
31
+ "system_message": self.system_message,
32
+ "code_execution_config": self.code_execution_config,
33
+ "human_input_mode": self.human_input_mode,
34
+ }
35
+
36
+
37
+
38
+
39
+ def make_agent(self, llm_config: Dict[str, Any]) -> UserProxyAgent:
40
+ return UserProxyAgent(**self.to_dict(), llm_config=llm_config)
app.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List
2
+ import streamlit as st
3
+ from tkinter import Tk, filedialog
4
+ from streamlit.components.v1 import html
5
+ from autogen import ConversableAgent
6
+
7
+
8
+ from ui.introductory_page import IntroductoryPage
9
+ from ui.analysis_page import NavigationPanel, CodePreview, ResultsDisplay
10
+
11
+
12
+ from agents.code_overview_agents import CodeSummarizerAgent, CodeSmellDetectorAgent
13
+ from agents.code_structure_agents import DesignPatternDetectorAgent, DesignPatternRecommenderAgent, SOLIDPrinciplesManagerAgent
14
+ from agents.code_visualization_agents import MermaideDiagramAgent
15
+
16
+
17
+ from config import DefaultSettings
18
+ from utils.utils import load_config, load_css
19
+
20
+
21
+
22
+
23
+
24
+ # Configuration and Agent Initialization
25
+ llm_config = load_config(DefaultSettings().default_model_type)
26
+ agents = [
27
+ CodeSummarizerAgent().make_agent(llm_config),
28
+ CodeSmellDetectorAgent().make_agent(llm_config),
29
+ DesignPatternDetectorAgent().make_agent(llm_config),
30
+ DesignPatternRecommenderAgent().make_agent(llm_config),
31
+ SOLIDPrinciplesManagerAgent().make_agent(llm_config),
32
+ MermaideDiagramAgent().make_agent(llm_config)
33
+ ]
34
+
35
+
36
+
37
+ class AnalysisManager:
38
+ """Manages and provides access to analysis results."""
39
+
40
+ def __init__(self, results):
41
+ load_css("./ui/styles.css")
42
+ self.results = results
43
+
44
+ def get_file_data(self, file_path):
45
+ return self.results.get(file_path, {})
46
+
47
+ def list_files(self):
48
+ return list(self.results.keys())
49
+
50
+
51
+
52
+ class CodeAnalysisApp:
53
+ """Main application orchestrator."""
54
+
55
+
56
+ def __init__(self, agents: List[ConversableAgent]) -> None:
57
+ self.agents = agents
58
+
59
+ def run(self):
60
+ """Main application entry point."""
61
+ st.set_page_config(
62
+ layout="wide",
63
+ initial_sidebar_state="expanded",
64
+ page_icon="🔍"
65
+ )
66
+
67
+ if not self._check_analysis_state():
68
+ IntroductoryPage(self.agents).render()
69
+ return
70
+
71
+ self._setup_interface()
72
+ self._render_main_view()
73
+ self._add_reset_button()
74
+
75
+ def _check_analysis_state(self):
76
+ """Validate analysis completion status."""
77
+ if 'analysis_done' not in st.session_state:
78
+ st.session_state.analysis_done = False
79
+ return st.session_state.get('results') and st.session_state.analysis_done
80
+
81
+ def _setup_interface(self):
82
+ """Initialize application components."""
83
+ load_css("./ui/styles.css")
84
+ self.analysis = AnalysisManager(st.session_state.results)
85
+ self.nav = NavigationPanel(self.analysis.list_files())
86
+
87
+ def _render_main_view(self):
88
+ """Display main two-column interface."""
89
+ selected_file = self.nav.render()
90
+ file_data = self.analysis.get_file_data(selected_file)
91
+
92
+ col1, col2 = st.columns([0.5, 0.5])
93
+ with col1:
94
+ CodePreview(
95
+ file_path=selected_file,
96
+ language=file_data['language']
97
+ ).render()
98
+
99
+ with col2:
100
+ ResultsDisplay(
101
+ file_data['analysis_results']
102
+ ).render()
103
+
104
+ def _add_reset_button(self):
105
+ """Add sidebar reset functionality."""
106
+ st.sidebar.button(
107
+ "New Analysis",
108
+ on_click=self._reset_state
109
+ )
110
+
111
+ def _reset_state(self):
112
+ """Clear analysis-related session state."""
113
+ state_keys = ['results', 'analysis_done', 'selected_dir', 'prev_dir']
114
+ for key in state_keys:
115
+ if key in st.session_state:
116
+ del st.session_state[key]
117
+ st.rerun()
118
+
119
+
120
+ if __name__ == "__main__":
121
+ CodeAnalysisApp(agents).run()
config.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from pickle import DICT
3
+ from autogen import ConversableAgent, UserProxyAgent, AssistantAgent
4
+ from autogen.tools import tool
5
+
6
+
7
+ from typing import Dict, Any, List
8
+
9
+
10
+
11
+
12
+
13
+ # ----------------------------------------------------------------
14
+ # General Config
15
+ # ----------------------------------------------------------------
16
+
17
+
18
+ extension_to_language = {
19
+ '.py': 'Python',
20
+ '.js': 'JavaScript',
21
+ '.java': 'Java',
22
+ '.cpp': 'C++',
23
+ '.cxx': 'C++',
24
+ '.cc': 'C++',
25
+ '.c': 'C',
26
+ '.cs': 'C#',
27
+ '.rb': 'Ruby',
28
+ '.php': 'PHP',
29
+ '.html': 'HTML',
30
+ '.htm': 'HTML',
31
+ '.css': 'CSS',
32
+ '.ts': 'TypeScript',
33
+ '.go': 'Go',
34
+ '.rs': 'Rust',
35
+ '.swift': 'Swift',
36
+ '.kt': 'Kotlin',
37
+ '.m': 'Objective-C',
38
+ '.sh': 'Shell',
39
+ '.pl': 'Perl',
40
+ '.r': 'R',
41
+ '.lua': 'Lua',
42
+ '.scala': 'Scala',
43
+ '.sql': 'SQL',
44
+ '.dart': 'Dart',
45
+ '.jl': 'Julia',
46
+ '.json': 'JSON',
47
+ '.xml': 'XML',
48
+ '.yml': 'YAML',
49
+ '.yaml': 'YAML',
50
+ }
51
+
52
+
53
+
54
+ @dataclass
55
+ class DefaultSettings:
56
+ default_model_type: str = "google"
57
+ default_display_language: str = "python"
58
+
59
+
60
+
61
+
62
+
63
+ @dataclass
64
+ class BaseLLMConfig:
65
+ model_name: str
66
+ api_key: str
67
+ api_type: str
68
+ temperature: float
69
+ max_tokens: int
70
+
71
+ def get_llm_config(self):
72
+ return {'config_list': [
73
+ {'model': self.model_name,
74
+ 'api_key': self.api_key,
75
+ 'api_type': self.api_type}
76
+ ]}
77
+
78
+
79
+ @dataclass
80
+ class GeminiLLMConfig(BaseLLMConfig):
81
+ model_name: str = "gemini-2.0-flash"
82
+ api_key: str = "AIzaSyCYI-tm7QjAfYKKlb2wfdgnQ1aTmqh91GY"
83
+ api_type: str = "google"
84
+ temperature: float = 0.1
85
+ max_tokens: int = 1024
86
+
87
+
88
+
89
+ @dataclass
90
+ class OpenAILLMConfig(BaseLLMConfig):
91
+ model_name: str = "chatgpt-4"
92
+ api_key: str = "api-key"
93
+ api_type: str = "openai"
94
+ temperature: float = 0.1
95
+ max_tokens: int = 1024
96
+
97
+
98
+
99
+
requirements.txt CHANGED
@@ -1,3 +1,11 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
 
 
 
1
+ streamlit>=1.29.0
2
+ autogen>=0.8.5
3
+ tkinter>=8.6.0
4
+ python-dotenv>=1.0.0
5
+ pyyaml>=6.0.1
6
+ typing-extensions>=4.8.0
7
+ pytest>=7.4.3
8
+ pytest-cov>=4.1.0
9
+ black>=23.11.0
10
+ isort>=5.12.0
11
+ mypy>=1.7.0
run.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ import subprocess
2
+ subprocess.run(["streamlit", "run", "app.py"])
ui/__pycache__/analysis_page.cpython-311.pyc ADDED
Binary file (3.88 kB). View file
 
ui/__pycache__/code_container.cpython-311.pyc ADDED
Binary file (5.13 kB). View file
 
ui/__pycache__/introductory_page.cpython-311.pyc ADDED
Binary file (6.05 kB). View file
 
ui/analysis_page.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+
4
+ from utils.utils import load_css
5
+
6
+
7
+
8
+
9
+ class NavigationPanel:
10
+ """Renders the sidebar file navigation."""
11
+
12
+ def __init__(self, files):
13
+ self.files = files
14
+
15
+ def render(self):
16
+ load_css("./ui/styles.css")
17
+ with st.sidebar:
18
+ st.title("Code Analyis")
19
+
20
+ selected = st.selectbox(
21
+ "Select File",
22
+ self.files,
23
+ format_func=os.path.basename
24
+ )
25
+
26
+ return selected
27
+
28
+
29
+ class CodePreview:
30
+ """Displays file contents with syntax highlighting."""
31
+
32
+ def __init__(self, file_path, language):
33
+ load_css("./ui/styles.css")
34
+ self.file_path = file_path
35
+ self.language = language.lower()
36
+
37
+ def render(self):
38
+ st.header("Code Preview")
39
+ try:
40
+ with open(self.file_path, 'r') as f:
41
+ st.code(f.read(), language=self.language)
42
+ except FileNotFoundError:
43
+ st.error("File not found")
44
+
45
+
46
+ class ResultsDisplay:
47
+ """Presents analysis results in expandable sections."""
48
+
49
+ def __init__(self, results):
50
+ load_css("./ui/styles.css")
51
+ self.results = results
52
+
53
+ def render(self):
54
+ st.header("Analysis")
55
+ for agent, findings in self.results.items():
56
+ with st.expander(f"{agent}", expanded=False):
57
+ st.write(findings)
ui/introductory_page.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from tkinter import Tk, filedialog
4
+ import time
5
+
6
+ from utils.utils import analyze_directory_with_agents, load_css
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+ class IntroductoryPage:
15
+ """Handles directory selection and initial analysis."""
16
+
17
+ def __init__(self, agents):
18
+ self.agents = agents
19
+ self._init_session_state()
20
+
21
+ def _init_session_state(self):
22
+ required_state = {
23
+ 'analysis_done': False,
24
+ 'selected_dir': None,
25
+ 'prev_dir': None,
26
+ 'results': None
27
+ }
28
+ for key, val in required_state.items():
29
+ if key not in st.session_state:
30
+ st.session_state[key] = val
31
+
32
+ @staticmethod
33
+ def _select_directory():
34
+ """Open system directory picker."""
35
+ root = Tk()
36
+ root.withdraw()
37
+ root.wm_attributes('-topmost', 1)
38
+ directory = filedialog.askdirectory(parent=root)
39
+ root.destroy()
40
+ return directory
41
+
42
+ def _process_directory(self):
43
+ """Handle directory selection and analysis."""
44
+ directory = self._select_directory()
45
+
46
+ if not directory:
47
+ st.warning("No directory selected")
48
+ return
49
+
50
+ if not os.path.isdir(directory):
51
+ st.error("Invalid directory")
52
+ return
53
+
54
+ st.session_state.selected_dir = directory
55
+ self._analyze_directory(directory)
56
+
57
+
58
+ def _progress_bar_callback_func(
59
+ self,
60
+ current_idx: int,
61
+ file_path: str,
62
+ progress_value: int
63
+ ) -> None:
64
+ """
65
+ Callback function for `analyze_directory_with_agents`.
66
+ Updates the progress bar and status text with the current file being processed.
67
+ """
68
+ if current_idx == 0:
69
+ self.status_text.markdown("🔍 Analyzing code structure...")
70
+
71
+
72
+
73
+
74
+ progress_value = progress_value if progress_value < 100 else 100
75
+ self.progress_bar.progress(current_idx * progress_value)
76
+ self.status_text.markdown(f"Processing {file_path}")
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+ def _analyze_directory(self, directory):
85
+ """Run analysis on selected directory with progress bar."""
86
+ self.progress_bar = st.progress(0)
87
+ self.status_text = st.empty()
88
+
89
+ try:
90
+
91
+ st.session_state.results = analyze_directory_with_agents(
92
+ directory, self.agents, verbose=True, callback_func = self._progress_bar_callback_func
93
+ )
94
+
95
+ st.session_state.analysis_done = True
96
+ st.rerun()
97
+
98
+ except Exception as e:
99
+ self.status_text.empty()
100
+ st.error(f"Analysis failed: {str(e)}")
101
+ st.session_state.analysis_done = False
102
+ st.session_state.selected_dir = None
103
+
104
+ def render(self):
105
+ """Main entry point for introductory page."""
106
+ self._handle_state()
107
+
108
+ if not st.session_state.analysis_done:
109
+ self._render_selector()
110
+
111
+ def _render_selector(self):
112
+ """Render file selection interface."""
113
+ load_css("./ui/styles.css")
114
+ if st.button("Select Directory", key="start_button"):
115
+ self._process_directory()
116
+
117
+ def _handle_state(self):
118
+ """Manage session state transitions."""
119
+ if st.session_state.selected_dir != st.session_state.prev_dir:
120
+ st.session_state.analysis_done = False
121
+ st.session_state.prev_dir = st.session_state.selected_dir
ui/styles.css ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Hide Streamlit default UI elements */
2
+ #MainMenu, header, footer {
3
+ visibility: hidden;
4
+ }
5
+
6
+ /* Full-screen center layout */
7
+ .stApp {
8
+ display: flex;
9
+ justify-content: center;
10
+ align-items: center;
11
+ min-height: 100vh;
12
+ margin: 0;
13
+ padding: 0;
14
+ }
15
+
16
+ /* Global dark theme base */
17
+ body {
18
+ background-color: #343541; /* ChatGPT dark gray */
19
+ color: #ececf1; /* Light neutral for text */
20
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
21
+ margin: 0;
22
+ padding: 0;
23
+ }
24
+
25
+ /* Container centering */
26
+ .centered-container {
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ height: 100vh;
31
+ width: 100vw;
32
+ }
33
+
34
+ /* ChatGPT-style button */
35
+ .stButton > button {
36
+ background-color: #444654 !important;
37
+ color: #ececf1 !important;
38
+ border: 1px solid #5c5f72 !important;
39
+ border-radius: 999px !important;
40
+ padding: 0.5rem 1.25rem !important;
41
+ font-weight: 500;
42
+ transition: background-color 0.2s ease, transform 0.1s ease;
43
+ position: relative;
44
+ }
45
+
46
+ .stButton > button:hover {
47
+ background-color: #565869 !important;
48
+ transform: scale(1.03);
49
+ }
50
+
51
+ /* Sidebar styling */
52
+ [data-testid="stSidebar"] {
53
+ background-color: #202123;
54
+ color: #ececf1;
55
+ border-right: 1px solid #2d2f36;
56
+ min-width: 140px;
57
+ max-width: 250px;
58
+ transition: all 0.3s ease;
59
+ }
60
+
61
+ [data-testid="stSidebar"][aria-expanded="false"] {
62
+ margin-left: -250px;
63
+ }
64
+
65
+ [data-testid="stSidebar"] h1,
66
+ [data-testid="stSidebar"] h2,
67
+ [data-testid="stSidebar"] h3 {
68
+ color: #ececf1;
69
+ }
70
+
71
+ /* Markdown and text elements */
72
+ .stMarkdown, .stCaption, .stHeader {
73
+ color: #ececf1;
74
+ }
75
+
76
+ /* Dropdown styling */
77
+ select {
78
+ background-color: #3e3f4b;
79
+ color: #ececf1;
80
+ border: 1px solid #5c5f72;
81
+ border-radius: 6px;
82
+ padding: 6px 10px;
83
+ }
84
+
85
+ /* Selectbox refinements */
86
+ .stSelectbox {
87
+ cursor: pointer !important;
88
+ }
89
+ .stSelectbox input {
90
+ cursor: pointer !important;
91
+ caret-color: transparent !important;
92
+ }
93
+ .stSelectbox div[data-baseweb="select"] {
94
+ cursor: pointer !important;
95
+ }
96
+ .stSelectbox [role="option"] {
97
+ cursor: pointer !important;
98
+ }
99
+ .stSelectbox ::selection {
100
+ background: transparent !important;
101
+ }
102
+
103
+ /* General container */
104
+ .block-container {
105
+ padding: 15px !important;
106
+ margin: 15px !important;
107
+ max-width: 100% !important;
108
+ }
109
+
110
+ /* Progress bar */
111
+ .stProgress > div > div > div {
112
+ background-color: #10a37f !important; /* ChatGPT green */
113
+ }
114
+ .stProgress > div > div {
115
+ background-color: #3e3f4b !important;
116
+ height: 10px !important;
117
+ border-radius: 5px;
118
+ }
119
+
120
+ /* Loading or status text */
121
+ .st-emotion-cache-1q7spjk {
122
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
123
+ color: #ececf1 !important;
124
+ font-size: 1.1rem;
125
+ margin-bottom: 15px;
126
+ }
127
+
128
+ /* Optional animation (retained from your original) */
129
+ .rotate {
130
+ display: inline-block;
131
+ color: #10a37f;
132
+ animation: rotation 2s infinite linear;
133
+ }
134
+ @keyframes rotation {
135
+ from { transform: rotate(0deg); }
136
+ to { transform: rotate(359deg); }
137
+ }
138
+
139
+ /* Centered button containers */
140
+ .centered-button-container,
141
+ .button-container {
142
+ display: flex;
143
+ justify-content: center;
144
+ align-items: center;
145
+ text-align: center;
146
+ }
utils/__init__.py ADDED
File without changes
utils/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (145 Bytes). View file
 
utils/__pycache__/utils.cpython-311.pyc ADDED
Binary file (9.82 kB). View file
 
utils/utils.py ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from autogen import ConversableAgent
2
+
3
+ import os
4
+ from typing import List, Dict, Optional, Callable
5
+ import time
6
+ import streamlit as st
7
+
8
+ from config import DefaultSettings, GeminiLLMConfig, OpenAILLMConfig, extension_to_language
9
+
10
+
11
+
12
+ def load_css(file_path):
13
+ """Load and inject CSS styles from file."""
14
+ try:
15
+ with open(file_path, "r") as f:
16
+ css = f.read()
17
+ st.markdown(f"<style>{css}</style>", unsafe_allow_html=True)
18
+ except Exception as e:
19
+ st.error(f"Failed to load CSS: {str(e)}")
20
+
21
+
22
+
23
+ def load_config(
24
+ model_type: str) -> dict:
25
+ """
26
+ Load the configuration for a given model type.
27
+
28
+ Args:
29
+ - model_type (str): The type of model to load the config for. Supported options are 'google' and 'openai'.
30
+
31
+ Returns:
32
+ - dict: A dictionary containing the configuration for the specified model type.
33
+ """
34
+ if model_type == 'google':
35
+ return GeminiLLMConfig().get_llm_config()
36
+ elif model_type == 'openai':
37
+ return OpenAILLMConfig().get_llm_config()
38
+ else:
39
+ raise ValueError(f"Unsupported model type: {model_type}")
40
+
41
+
42
+
43
+
44
+
45
+
46
+ def get_directory_tree(
47
+ path: str,
48
+ indent: str = "",
49
+ exclude_folder: str = "__pycache__"
50
+ ) -> str:
51
+ """
52
+ Returns a tree-like string representation of the directory at 'path', skipping excluded folders.
53
+ """
54
+ result = ""
55
+ for item in os.listdir(path):
56
+ if item == exclude_folder:
57
+ continue
58
+ full_path = os.path.join(path, item)
59
+ if os.path.isdir(full_path):
60
+ result += f"{indent}📁 {item}/\n"
61
+ result += get_directory_tree(full_path, indent + " ", exclude_folder)
62
+ else:
63
+ result += f"{indent}📄 {item}\n"
64
+ return result
65
+
66
+
67
+
68
+
69
+ def detect_language_by_extension(file_path: str) -> str:
70
+ """
71
+ Detect the language of a file by its extension.
72
+
73
+ Args:
74
+ file_path (str): The path to the file to detect.
75
+
76
+ Returns:
77
+ str: The detected language.
78
+ """
79
+ _, ext = os.path.splitext(file_path.lower())
80
+ return extension_to_language.get(ext, 'Unknown')
81
+
82
+
83
+
84
+
85
+
86
+ def get_supported_code_files(directory_path: str) -> List[str]:
87
+ """
88
+ Scans a directory for files with supported programming language extensions.
89
+
90
+ Args:
91
+ directory_path (str): Path to the directory to scan
92
+
93
+ Returns:
94
+ List[str]: List of absolute paths to supported code files
95
+ """
96
+ code_files = []
97
+ for root, _, files in os.walk(directory_path):
98
+ for file in files:
99
+ _, ext = os.path.splitext(file)
100
+ if ext in extension_to_language:
101
+ full_path = os.path.join(root, file)
102
+ code_files.append(full_path)
103
+ return code_files
104
+
105
+ def analyze_code_with_agents(
106
+ source_code: str,
107
+ analysis_agents: List[ConversableAgent]
108
+ ) -> Dict[str, str]:
109
+ """
110
+ Analyzes source code using multiple code analysis agents.
111
+
112
+ Args:
113
+ source_code (str): The code to analyze
114
+ analysis_agents (List[ConversableAgent]): List of agents to perform analysis
115
+
116
+ Returns:
117
+ Dict[str, str]: A dictionary mapping each agent's name to its analysis result
118
+ """
119
+ results = {}
120
+ for agent in analysis_agents:
121
+ agent_response = agent.generate_reply(messages=[{'role': 'user', 'content': source_code}])
122
+ results[agent.name] = agent_response['content']
123
+ return results
124
+
125
+ def analyze_code_file(
126
+ file_path: str,
127
+ analysis_agents: List[ConversableAgent]
128
+ ) -> Optional[Dict[str, str]]:
129
+ """
130
+ Analyzes a single code file using multiple analysis agents.
131
+
132
+ Args:
133
+ file_path (str): Path to the code file to analyze
134
+ analysis_agents (List[ConversableAgent]): List of agents to perform analysis
135
+
136
+ Returns:
137
+ Optional[Dict[str, str]]: Analysis results if successful, None if an error occurred
138
+ """
139
+ try:
140
+ with open(file_path, 'r', encoding='utf-8') as file:
141
+ code = file.read()
142
+
143
+ analysis_results = analyze_code_with_agents(code, analysis_agents)
144
+ return analysis_results
145
+
146
+ except UnicodeDecodeError:
147
+ print(f"Skipping binary file {file_path}")
148
+ return None
149
+ except PermissionError:
150
+ print(f"Permission denied for file {file_path}")
151
+ return None
152
+ except Exception as e:
153
+ print(f"Error processing file {file_path}: {str(e)}")
154
+ return None
155
+
156
+ def analyze_directory_with_agents(
157
+ directory_path: str,
158
+ analysis_agents: List[ConversableAgent],
159
+ time_between_analysis: int = 10,
160
+ verbose: bool = False,
161
+ callback_func: Callable[[int], None] = None
162
+ ) -> Dict[str, Dict[str, str]]:
163
+ """
164
+ Analyzes all code files in a directory using multiple analysis agents.
165
+
166
+ Args:
167
+ directory_path (str): Path to the directory to analyze
168
+ analysis_agents (List[ConversableAgent]): List of agents to perform analysis
169
+ verbose (bool): Whether to print verbose output (default: False)
170
+
171
+ Returns:
172
+ Dict[str, Dict[str, str]]: A nested dictionary where:
173
+ - Outer keys are file paths
174
+ - Inner keys are agent names
175
+ - Values are agent analysis results
176
+ """
177
+ if verbose:
178
+ print(f"Started Analyzing using these agents {[agent.name for agent in analysis_agents]} [+]")
179
+
180
+ analysis_results = {}
181
+
182
+ # Get all supported code files in the directory
183
+ code_files = get_supported_code_files(directory_path)
184
+
185
+ # Progress Value
186
+ progress_value = int( 100 / (len(code_files) + 1))
187
+
188
+ # Process each code file
189
+ for idx, file_path in enumerate(code_files):
190
+ if callback_func:
191
+ callback_func(idx, file_path, progress_value)
192
+
193
+ try:
194
+ agents_names = [agent.name for agent in analysis_agents]
195
+ file_language = detect_language_by_extension(file_path)
196
+ file_analysis = analyze_code_file(file_path, analysis_agents)
197
+
198
+ if file_analysis is not None:
199
+ analysis_results[file_path] = {
200
+ "language": file_language,
201
+ "analysis_results": file_analysis
202
+ }
203
+
204
+ if verbose:
205
+ print(f"Analyzed {file_path} Successfully using agents {agents_names} [+]")
206
+
207
+ except Exception as e:
208
+ print(f"Error processing file {file_path}: {str(e)}")
209
+ continue
210
+
211
+
212
+
213
+ time.sleep(time_between_analysis)
214
+
215
+ if verbose:
216
+ print(f"Analyzed {len(code_files)} files in {directory_path}")
217
+
218
+ return analysis_results