diff --git a/ArrowVegaLiteChart.B5mh1aU6.js b/ArrowVegaLiteChart.B5mh1aU6.js new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index e2ce93d..120898d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -42,3 +42,4 @@ urllib3==2.7.0 uvicorn==0.47.0 watchdog==6.0.0 websockets==16.0 +python-dotenv>=1.0.0 \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py index 9c12fce..29c2b2b 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,12 +1,12 @@ -# # src/__init__.py +# src/__init__.py -# # Initialisierung des Pakets -# __version__ = "1.0.0" +# Initialisierung des Pakets +__version__ = "1.0.0" -# # Export der wichtigsten Module -# from .backend.file_manager import FileManager -# from .backend.chat_manager import ChatManager -# from .backend.system_prompter import SystemPrompter -# from .backend.search_manager import SearchManager -# from .backend.execution_engine import ExecutionEngine -# from .backend.debug_logger import DebugLogger \ No newline at end of file +# Export der wichtigsten Module +from .backend.file_manager import FileManager +from .backend.chat_manager import ChatManager +from .backend.system_prompter import SystemPrompter +from .backend.search_manager import SearchManager +from .backend.execution_engine import ExecutionEngine +from .backend.debug_logger import DebugLogger \ No newline at end of file diff --git a/src/backend/__init__.py b/src/backend/__init__.py index e2a2ff7..43e455c 100644 --- a/src/backend/__init__.py +++ b/src/backend/__init__.py @@ -1,6 +1,6 @@ -# from .file_manager import FileManager -# from .chat_manager import ChatManager -# from .system_prompter import SystemPrompter -# from .search_manager import SearchManager -# from .execution_engine import ExecutionEngine -# from .debug_logger import DebugLogger \ No newline at end of file +from .file_manager import FileManager +from .chat_manager import ChatManager +from .system_prompter import SystemPrompter +from .search_manager import SearchManager +from .execution_engine import ExecutionEngine +from .debug_logger import DebugLogger \ No newline at end of file diff --git a/src/backend/chat_manager.py b/src/backend/chat_manager.py index e69de29..4d01ea0 100644 --- a/src/backend/chat_manager.py +++ b/src/backend/chat_manager.py @@ -0,0 +1,15 @@ +class ChatManager: + """ + Platzhalter für die Chat-Kommunikation [1] + """ + def __init__(self): + self.conversation_history = [] + + def generate_response(self, prompt): + """ + Gibt eine Dummy-Antwort zurück [1] + """ + return "Antwort (Backend-Logik noch nicht implementiert)" + + def get_history(self): + return [] \ No newline at end of file diff --git a/src/backend/debug_logger.py b/src/backend/debug_logger.py index e69de29..d45e9a2 100644 --- a/src/backend/debug_logger.py +++ b/src/backend/debug_logger.py @@ -0,0 +1,12 @@ +class DebugLogger: + """ + Platzhalter für das Logging [1] + """ + def __init__(self): + self.logs = [] + + def log(self, message): + self.logs.append(message) + + def get_logs(self): + return self.logs \ No newline at end of file diff --git a/src/backend/execution_engine.py b/src/backend/execution_engine.py index e69de29..67cfd1b 100644 --- a/src/backend/execution_engine.py +++ b/src/backend/execution_engine.py @@ -0,0 +1,12 @@ +class ExecutionEngine: + """ + Platzhalter für die Code-Ausführung [1] + """ + def __init__(self): + pass + + def execute_code(self): + """ + Führt Code nicht aus, sondern gibt einen Status aus [1] + """ + return "Code wurde nicht ausgeführt (Platzhalter)" \ No newline at end of file diff --git a/src/backend/file_manager.py b/src/backend/file_manager.py index e69de29..8c9532e 100644 --- a/src/backend/file_manager.py +++ b/src/backend/file_manager.py @@ -0,0 +1,50 @@ +import os +from pathlib import Path + +class FileManager: + """ + Verwaltet das Laden, Speichern und Auflisten von Code-Dateien inklusive Ordnerstruktur [1] + """ + def __init__(self, root_path="."): + self.root_path = Path(root_path).resolve() + + def list_files(self, current_path=None): + """ + Gibt eine verschachtelte Struktur zurück, um Ordner und Dateien darzustellen [1] + """ + if current_path is None: + current_path = self.root_path + elif not isinstance(current_path, Path): + current_path = Path(current_path) + + items = [] + try: + for item in current_path.iterdir(): + if item.is_dir(): + items.append({"type": "folder", "name": item.name, "path": str(item)}) + elif item.is_file() and item.suffix in {'.py', '.js', '.html', '.css', '.md'}: + items.append({"type": "file", "name": item.name, "path": str(item)}) + except PermissionError: + pass + return items + + def read_file(self, file_path): + """ + Liest und gibt den Inhalt einer Datei zurück [1] + """ + try: + with open(file_path, 'r', encoding='utf-8') as f: + return f.read() + except Exception as e: + return None + + def save_file(self, file_path, content): + """ + Schreibt Inhalt in eine Datei [1] + """ + try: + with open(file_path, 'w', encoding='utf-8') as f: + f.write(content) + return True + except Exception: + return False \ No newline at end of file diff --git a/src/backend/search_manager.py b/src/backend/search_manager.py index e69de29..c8f1411 100644 --- a/src/backend/search_manager.py +++ b/src/backend/search_manager.py @@ -0,0 +1,30 @@ +class SearchManager: + """ + Verwaltet Suchanfragen und integriert externe APIs [1] + """ + def __init__(self, api_key=None): + self.api_key = api_key + self.search_history = [] + + def perform_search(self, query): + """ + Führt eine Internetsuche aus [1] + """ + # Platzhalter-Implementierung für Startphase + return [] + + def parse_results(self, raw_results): + """ + Extrahiert und formatiert relevante Ergebnisse [1] + """ + # Rückgabe einer formatierten Liste als Platzhalter + if isinstance(raw_results, list): + return raw_results + return [] + + def search_context(self, query, context_type="web"): + """ + Fügt Suchergebnisse dem Kontext hinzu + """ + results = self.perform_search(query) + return f"Search results for '{query}': {results}" \ No newline at end of file diff --git a/src/backend/system_prompter.py b/src/backend/system_prompter.py index e69de29..3187608 100644 --- a/src/backend/system_prompter.py +++ b/src/backend/system_prompter.py @@ -0,0 +1,28 @@ +class SystemPrompter: + """ + Generiert System-Prompts mit Dateikontext für die KI [1] + """ + def __init__(self): + self.default_prompt = "You are a code assistant helping to debug Python code." + + def generate_prompt(self, user_message, file_context): + """ + Baut ein vollständiges Prompt mit Dateiinhalten oder Kontextinformationen auf [1] + """ + # Platzhalter-Implementierung für Startphase + return f"User: {user_message}\nContext: {file_context}" + + def add_context(self, file_name, code_snippet=None): + """ + Fügt Dateikontext hinzu (Dateiname, Änderungen oder markierte Code-Abschnitte) [1] + """ + context = f"File: {file_name}" + if code_snippet: + context += f"\nCode:\n{code_snippet}" + return context + + def summarize_context(self, context): + """ + Fasst Kontext zusammen, um den Prompt nicht zu überladen [1] + """ + return context[:500] if len(context) > 500 else context \ No newline at end of file diff --git a/src/main.py b/src/main.py index e69de29..ef431ac 100644 --- a/src/main.py +++ b/src/main.py @@ -0,0 +1,72 @@ +import sys +import os +project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +if project_root not in sys.path: + sys.path.insert(0, project_root) + +import streamlit as st + +# Backend-Imports +from src.backend.file_manager import FileManager +from src.backend.chat_manager import ChatManager +from src.backend.execution_engine import ExecutionEngine + +# UI-Imports +from src.ui.navigation import FileNavigation +from src.ui.editor import CodeEditor +from src.ui.chat import ChatInterface +from src.ui.output import OutputDisplay + +def main(): + st.set_page_config( + page_title="AI Code Editor", + page_icon="💻", + layout="wide" + ) + + # Initialisiere Manager-Klassen + file_manager = FileManager() + chat_manager = ChatManager() + execution_engine = ExecutionEngine() + + + if "selected_file" not in st.session_state: + st.session_state.selected_file = None + if "file_history" not in st.session_state: + st.session_state.file_history = [] + + # Sidebar für Dateinavigation + st.sidebar.title("📁 Datei-Explorer") + st.sidebar.subheader("Wähle eine Datei aus") + + navigation = FileNavigation() + file_list = navigation.list_files() + + if file_list: + selected_file = st.sidebar.selectbox("Dateien", file_list) + if selected_file: + content = file_manager.read_file(selected_file) + st.session_state.selected_file = selected_file + + col1, col2 = st.columns([3, 2]) + + with col1: + editor = CodeEditor() + editor.display_code(content) + + if st.button("💾 Speichern"): + file_manager.save_file(selected_file, content) + st.success("Datei gespeichert!") + + with col2: + chat = ChatInterface() + chat.display_chat(chat_manager) + + output = OutputDisplay() + output.display_execution(execution_engine) + + st.sidebar.markdown("---") + st.sidebar.caption("AISE501 – AI in Software Engineering") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/ui/__init__.py b/src/ui/__init__.py index eac8644..6003886 100644 --- a/src/ui/__init__.py +++ b/src/ui/__init__.py @@ -1,6 +1,6 @@ -# # src/ui/__init__.py +# src/ui/__init__.py -# from .navigation import FileNavigation -# from .editor import CodeEditor -# from .chat import ChatInterface -# from .output import OutputDisplay \ No newline at end of file +from .navigation import FileNavigation +from .editor import CodeEditor +from .chat import ChatInterface +from .output import OutputDisplay \ No newline at end of file diff --git a/src/ui/chat.py b/src/ui/chat.py index e69de29..a5711fd 100644 --- a/src/ui/chat.py +++ b/src/ui/chat.py @@ -0,0 +1,45 @@ +import streamlit as st + +class ChatInterface: + """ + Chat Interface für KI-Interaktion [1] + """ + + def __init__(self): + self.chat_messages = [] + + def display_chat(self, chat_manager): + """ + Zeigt die Chat-Schnittstelle mit Konversationsverlauf [1] + """ + st.title("🤖 KI-Assistent") + + # Chat History anzeigen + for message in self.chat_messages: + with st.chat_message(message["role"]): + st.markdown(message["content"]) + + # User Input + if prompt := st.chat_input("Frage zum Code stellen..."): + # User Nachricht anzeigen + self.chat_messages.append({"role": "user", "content": prompt}) + with st.chat_message("user"): + st.markdown(prompt) + + # AI Antwort generieren (via ChatManager) + with st.chat_message("assistant"): + response = chat_manager.generate_response(prompt) + st.markdown(response) + self.chat_messages.append({"role": "assistant", "content": response}) + + def add_message(self, role, content): + """ + Fügt eine Nachricht zur Konversation hinzu + """ + self.chat_messages.append({"role": role, "content": content}) + + def clear_history(self): + """ + Löscht den Chat-Verlauf + """ + self.chat_messages.clear() \ No newline at end of file diff --git a/src/ui/editor.py b/src/ui/editor.py index e69de29..63f9ec2 100644 --- a/src/ui/editor.py +++ b/src/ui/editor.py @@ -0,0 +1,30 @@ +import streamlit as st + +class CodeEditor: + """ + Code Editor & Anzeige Komponente [1] + """ + def __init__(self): + self.language = "python" + self.show_line_numbers = True + + def display_code(self, code_content): + """ + Zeigt den Code-Editor mit Inhalt an + """ + if code_content: + st.code(code_content, language=self.language) + else: + st.info("Bitte wählen Sie eine Datei aus der Sidebar aus") + + def get_code_content(self): + """ + Liest den aktuellen Code-Inhalt vom Editor + """ + return st.session_state.get("code_content", "") + + def update_code_content(self, new_content): + """ + Aktualisiert den Code-Inhalt im Session State + """ + st.session_state.code_content = new_content \ No newline at end of file diff --git a/src/ui/navigation.py b/src/ui/navigation.py index e69de29..81d4bd8 100644 --- a/src/ui/navigation.py +++ b/src/ui/navigation.py @@ -0,0 +1,30 @@ +import os +from pathlib import Path + +class FileNavigation: + """ + Navigation für die Dateiauswahl in der Sidebar [1] + """ + + def __init__(self): + self.supported_extensions = {'.py', '.js', '.html', '.css', '.json', '.md'} + + def list_files(self, path=None): + """ + Listet alle Code-Dateien im aktuellen Verzeichnis auf [1] + """ + if path is None: + path = Path.cwd() + + file_list = [] + for root, dirs, files in os.walk(path): + for file in files: + if os.path.splitext(file)[1] in self.supported_extensions: + file_list.append(file) + return sorted(file_list) + + def get_full_path(self, filename): + """ + Gibt den vollständigen Pfad der Datei zurück + """ + return Path(filename) \ No newline at end of file diff --git a/src/ui/output.py b/src/ui/output.py index e69de29..b0e16df 100644 --- a/src/ui/output.py +++ b/src/ui/output.py @@ -0,0 +1,42 @@ +import streamlit as st + +class OutputDisplay: + """ + Display für Execution Results und Debugging [1] + """ + + def __init__(self): + self.execution_output = [] + + def display_execution(self, execution_engine): + """ + Zeigt die Ergebnisse der Code-Ausführung an [1] + """ + st.title("🔍 Execution Output") + + # Ausgabe-Fenster erstellen + output_area = st.empty() + + # Code Execution Button + if st.button("▶️ Code ausführen"): + with output_area: + with st.spinner("Code wird ausgeführt..."): + result = execution_engine.execute_code() + output_area.code(result, language="python") + + # Fehler-Logging anzeigen + if st.checkbox("Debug Logs anzeigen"): + st.subheader("🐛 Debug Logs") + st.text_area("Logs", height=200) + + def display_error(self, error_message): + """ + Zeigt Fehlermeldungen an + """ + st.error(f"❌ Fehler: {error_message}") + + def display_warning(self, warning_message): + """ + Zeigt Warnungen an + """ + st.warning(f"⚠️ Warnung: {warning_message}") \ No newline at end of file