diff --git a/README.md b/README.md index 7fc8b13..135e3e2 100644 --- a/README.md +++ b/README.md @@ -1,224 +1,168 @@ -# AISE AI Agent — Code Editor & Coding Assistant +# AISE AI Code Editor -Ein browserbasierter Code-Editor mit integriertem AI-Chat und autonomem Coding-Agent, gebaut mit Streamlit und dem Model Context Protocol (MCP). - ---- - -## Installation & Setup - -**Voraussetzungen:** Python 3.13+, pip - -```bash -# 1. Repository klonen und ins Verzeichnis wechseln -cd AISE_AIAgent - -# 2. Virtuelle Umgebung erstellen und aktivieren -python -m venv .venv -.venv\Scripts\activate # Windows -# source .venv/bin/activate # macOS/Linux - -# 3. Abhängigkeiten installieren -pip install -r requirements.txt - -# 4. Umgebungsvariablen konfigurieren -copy .env.example .env -# .env öffnen und HOST, PORT, API_KEY, MODEL eintragen -``` - -**`.env` Konfiguration:** -``` -HOST=silicon.fhgr.ch -PORT=7080 -API_KEY=EMPTY -MODEL=qwen3.5-35b-a3b -``` - ---- - -## Starten - -```bash -# Streamlit App (Hauptinterface) -streamlit run frontend/app.py - -# Coding Agent direkt im Terminal testen -python run_agent.py -``` - ---- +AI-Supported Lightweight Code Editor built with Streamlit (AISE501 Spring 2026) ## Projektstruktur ``` AISE_AIAgent/ -├── frontend/ # Streamlit UI -├── backend/ -│ ├── agent/ # Coding Agent + MCP-Adapter -│ │ └── servers/ # MCP-Server (Tools für den Agent) -│ └── managers/ # Business-Logik (Chat, Dateien, Ausführung) -├── workspace/ # Arbeitsverzeichnis des Agents & Editors -└── run_agent.py # CLI-Test für den Coding Agent +├── frontend/ # Streamlit UI-Komponenten +│ ├── app.py # Haupteinstiegspunkt der Streamlit-App +│ ├── state.py # Session-State-Verwaltung +│ ├── sidebar.py # Datei-Navigation (Sidebar) +│ ├── editor.py # Code-Editor-Pane +│ └── chat.py # Chat-Interface +│ +├── backend/ # Backend-Logik +│ ├── managers/ # Business-Logik für UI-Operationen +│ │ ├── file_manager.py # Datei-CRUD (lesen, schreiben, listen) +│ │ ├── chat_manager.py # AI-Chat-Verwaltung und -History +│ │ ├── system_prompter.py # System-Prompts und Kontext-Injektion +│ │ ├── search_manager.py # Web-Suche (DuckDuckGo) +│ │ ├── execution_engine.py # Code-Ausführung und Sandboxing +│ │ └── debug_logger.py # Logging, Fehlerbehandlung, Debug-Ausgaben +│ │ +│ └── agent/ # Autonomes AI-Agent-System (MCP-basiert) +│ ├── coding_agent.py # Haupt-Agent-Loop (Plan-Act-Observe) +│ ├── mcp_server_adapter.py # MCP-Adapter: verbindet Agent mit MCP-Servern +│ ├── mcp_server_adapter_RAG.py # MCP-Adapter mit RAG-basierter Tool-Auswahl +│ ├── mcp_server_config.json # Konfiguration der MCP-Server (Startbefehle) +│ └── servers/ # MCP-Server-Implementierungen +│ ├── mcp_server_code_execution.py # Tool: Python-Code ausführen +│ ├── mcp_server_file_search.py # Tool: Dateien suchen und lesen +│ └── mcp_server_web_search.py # Tool: Web-Suche via DuckDuckGo +│ +├── tests/ # Unit-Tests (pytest) +│ ├── conftest.py # Globale Test-Fixtures und MCP-Mocks +│ ├── test_file_manager.py +│ ├── test_chat_manager.py +│ ├── test_execution_engine.py +│ ├── test_coding_agent.py +│ ├── test_debug_logger.py +│ ├── test_system_prompter.py +│ ├── test_mcp_server_code_execution.py +│ ├── test_mcp_server_file_search.py +│ └── test_mcp_server_web_search.py +│ +├── workspace/ # Agent-Sandbox (isoliertes Arbeitsverzeichnis) +├── run_agent.py # CLI-Einstiegspunkt für den Coding-Agent +└── .env.example # Vorlage für Umgebungsvariablen ``` ---- +## Komponenten -## Frontend +### Frontend (`frontend/`) +- **app.py**: Streamlit-Applikation, Layout-Orchestrierung +- **state.py**: Zentralisierte Session-State-Verwaltung +- **sidebar.py**: Datei-Browser und Projekt-Navigation +- **editor.py**: Code-Editor mit Syntax-Highlighting +- **chat.py**: AI-Assistent Chat-Interface -### `frontend/app.py` — Einstiegspunkt -Initialisiert die Streamlit-App, setzt das Layout und routet zwischen Code-Editor und Chat-Ansicht basierend auf der Sidebar-Navigation. +### Backend Manager (`backend/managers/`) +Werden direkt vom Frontend für UI-Operationen genutzt: +- **file_manager.py**: CRUD-Operationen auf Projektdateien +- **chat_manager.py**: Chat-History, Nachrichten-Verwaltung +- **system_prompter.py**: System-Prompt-Generierung und Datei-Kontext +- **execution_engine.py**: Sichere Code-Ausführung mit Output-Capture +- **debug_logger.py**: Fehler-Tracking und Log-Formatierung +- **search_manager.py**: Web-Suche via DuckDuckGo (`ddgs`-Bibliothek) -### `frontend/state.py` — Session State -Initialisiert alle Streamlit `session_state`-Variablen beim App-Start (offene Dateien, Chat-Verlauf, Agent-Status etc.). Verhindert `KeyError` beim ersten Laden. +### Backend Agent (`backend/agent/`) +Autonomes AI-Agent-System für komplexe Coding-Aufgaben: +- **coding_agent.py**: Agent-Loop (Plan → Act → Observe → Wiederholen) +- **mcp_server_adapter.py**: Verbindet den Agent mit MCP-Servern via Konfigurationsdatei +- **mcp_server_adapter_RAG.py**: Erweiterter Adapter mit semantischer Tool-Auswahl (RAG) +- **mcp_server_config.json**: Definiert welche MCP-Server gestartet werden und mit welchen Argumenten +- **servers/**: Die eigentlichen MCP-Tool-Server (Code-Ausführung, Datei-Suche, Web-Suche) -### `frontend/sidebar.py` — Sidebar & File Explorer -- **Navigation:** Radio-Button zum Wechseln zwischen "Code Editor" und "Chat with AI Assistant" -- **File Tree:** Interaktiver Dateibaum (via `streamlit-arborist`) zeigt den `workspace/`-Ordner -- **Datei-Aktionen:** Datei öffnen, umbenennen, löschen -- **Ordner-Aktionen:** Ordner erstellen, Dateien in Ordner hinzufügen, Ordner löschen +### Workspace (`workspace/`) +- Sandbox-Verzeichnis, in dem der Agent Dateien erstellt und ausführt +- Verhindert, dass der Agent auf Dateien ausserhalb dieses Verzeichnisses zugreift -### `frontend/editor.py` — Code-Editor -- **Ace Editor:** Syntax-Highlighting für Python, JS, HTML, CSS, JSON, YAML, LaTeX u.a. -- **Tabs:** Mehrere Dateien gleichzeitig offen, Tab-Wechsel per Klick -- **Datei-Operationen:** Speichern, Schliessen, Umbenennen, Löschen direkt im Tab -- **Code ausführen:** Button "▶ Run Code" führt die aktive Datei aus, Output wird darunter angezeigt -- **Debug with AI:** Bei Fehlern erscheint ein Button der den Fehler + Code automatisch an den AI-Chat weiterleitet +## Features -### `frontend/chat.py` — Chat & Agent Mode +- **Datei-Verwaltung**: Dateien im Workspace durchsuchen und bearbeiten +- **Chat-Interface**: KI-gestützter Code-Assistent +- **Code-Ausführung**: Python-Code sicher ausführen mit Debug-Output +- **Web-Suche**: Dokumentation und Beispiele via DuckDuckGo abrufen +- **Autonomer Agent**: MCP-basierter Coding-Agent mit Plan-Act-Observe-Loop +- **RAG Tool-Auswahl**: Semantische Tool-Selektion via Sentence Transformers -**Normaler Chat (`render_normal_chat`):** -- Multi-Turn Konversation mit dem konfigurierten LLM -- Injiziert die aktuell offene Datei automatisch als Kontext in den System-Prompt -- Einstellungen: Modell wählen, Max Tokens, eigener System-Prompt -- "Clear Chat" mit Bestätigungsdialog +## Setup -**Agent Mode (`render_agent_mode`):** -- Autonomer Coding-Agent im Step-by-Step Modus -- Benutzer gibt eine Aufgabe ein, der Agent schlägt Aktionen vor -- Jede Aktion muss einzeln **genehmigt (Approve)** oder **abgelehnt (Reject)** werden -- **Agent Log:** Zeigt alle ausgeführten Schritte mit Tool, Gedanken und Resultat -- **Follow-up:** Nach Abschluss einer Aufgabe können Korrekturen eingegeben werden - ---- - -## Backend — Managers - -### `backend/managers/chat_manager.py` — ChatManager -Verwaltet den Konversationsverlauf und kommuniziert mit dem LLM über eine OpenAI-kompatible REST-API. Sendet bei jedem Request den gesamten Verlauf als Kontext mit. - -| Methode | Beschreibung | -|---|---| -| `send_message(user_message)` | Nachricht senden, Antwort zurückgeben, History updaten | -| `add_message(role, content)` | Nachricht manuell zur History hinzufügen | -| `clear_history()` | Gesamten Chat-Verlauf löschen | -| `get_history()` | Kopie des aktuellen Verlaufs zurückgeben | - -### `backend/managers/file_manager.py` — FileManager -Alle Datei- und Ordneroperationen innerhalb des `workspace/`-Verzeichnisses. Jede Operation validiert den Pfad gegen Path-Traversal-Angriffe. - -| Methode | Beschreibung | -|---|---| -| `create_file(relative_path, name)` | Neue Datei im Workspace erstellen | -| `create_folder(relative_path, name)` | Neuen Ordner erstellen | -| `read_file(path)` | Dateiinhalt lesen | -| `save_file(path, content)` | Datei speichern/überschreiben | -| `rename_file(old_path, new_name)` | Datei umbenennen (Extension bleibt erhalten) | -| `delete_file(relative_path)` | Datei löschen | -| `delete_folder(relative_path)` | Ordner inkl. Inhalt löschen | -| `get_file_tree()` | Verschachteltes Dict des gesamten Workspace-Baums | - -### `backend/managers/execution_engine.py` — ExecutionEngine -Führt Dateien aus dem Editor in einem Subprocess aus. Unterstützt Python (`.py`) und LaTeX (`.tex`). Timeout: 30 Sekunden. - -| Methode | Beschreibung | -|---|---| -| `run_code(active_file)` | Datei ausführen, gibt `{stdout, stderr, rc}` zurück | - -### `backend/managers/system_prompter.py` — SystemPrompter -Generiert den System-Prompt für den AI-Chat. Wenn eine Datei im Editor offen ist, wird ihr Inhalt (max. 4000 Zeichen) automatisch eingebettet. - -| Methode | Beschreibung | -|---|---| -| `generate_prompt(file_context)` | System-Prompt mit optionalem Datei-Kontext bauen | - -### `backend/managers/debug_logger.py` — DebugLogger -Einfacher In-Memory-Logger für den Code-Editor (Ausführungsstatus, Fehler). - ---- - -## Backend — Coding Agent - -### `backend/agent/coding_agent.py` — CodingAgent -Autonomer Agent nach dem **Plan → Act → Observe → Fix → Done** Loop. Kommuniziert mit dem LLM und ruft MCP-Tools über den Adapter auf. - -| Methode | Beschreibung | -|---|---| -| `start_task(task)` | Neue Aufgabe initialisieren, State zurücksetzen | -| `propose_next_action()` | LLM fragen was als nächstes zu tun ist (führt nichts aus) | -| `approve()` | Vorgeschlagene Aktion ausführen, nächsten Schritt vorschlagen | -| `reject(feedback)` | Aktion ablehnen, Feedback injizieren, Agent plant neu | -| `follow_up(question)` | Folgefrage nach abgeschlossener Aufgabe stellen | - -**Hilfsfunktionen:** -- `dispatch_tool(tool_name, arguments)` — Leitet Tool-Aufrufe an den MCP-Adapter weiter -- `build_all_tool_description()` — Generiert die Tool-Beschreibung für den System-Prompt -- `extract_json(text)` / `_repair_json_strings(text)` — Parst und repariert LLM-JSON-Antworten -- `trim_messages(messages)` — Kürzt alte History wenn Kontextfenster voll wird - -### `backend/agent/mcp_server_adapter.py` — MCPToolAdapter -Verbindet den Coding Agent mit den MCP-Servern. Liest die Konfiguration aus `mcp_server_config.json`, registriert alle verfügbaren Tools und startet bei jedem Tool-Aufruf eine frische stdio-Verbindung zum zuständigen Server. - -| Methode | Beschreibung | -|---|---| -| `initialize_all_servers()` | Alle Server verbinden und Tools registrieren | -| `call_tool(tool_name, arguments)` | Tool auf dem zuständigen Server aufrufen | -| `get_all_tools()` | Liste aller registrierten Tools zurückgeben | - ---- - -## MCP-Server (Tools für den Agent) - -Alle Server laufen als eigenständige Prozesse und kommunizieren über `stdio`. - -### `backend/agent/servers/mcp_server_code_execution.py` — CodeExecutionServer - -| Tool | Beschreibung | -|---|---| -| `run_python_sandboxed(code)` | Python-Code sicher ausführen (statische Analyse + Subprocess mit isoliertem stdin) | -| `python_code_validation(code)` | Syntax und Sicherheit prüfen ohne auszuführen | -| `lint_code(code)` | Statische Analyse mit pyflakes (ungenutzte Imports, undefinierte Variablen) | -| `analyse_structure(code)` | Struktur-Zusammenfassung (Klassen, Funktionen, Imports) | - -**Sicherheitsmechanismen:** Blockierte Imports (`os`, `sys`, `subprocess` etc.), blockierte Builtins (`exec`, `eval`, `open` etc.), verbotene Pfadsequenzen, Timeout nach 45 Sekunden. - -### `backend/agent/servers/mcp_server_file_search.py` — FileSearchServer - -| Tool | Beschreibung | -|---|---| -| `list_files()` | Alle Dateien im Workspace auflisten | -| `get_file_tree(dir_path)` | Verzeichnisbaum anzeigen | -| `search_files(query)` | Dateien nach Name oder Inhalt durchsuchen | -| `read_file(path)` | Dateiinhalt lesen | -| `write_new_file(path, content)` | Neue Datei erstellen (keine Überschreibung bestehender Dateien) | -| `create_new_directory(path)` | Neues Verzeichnis erstellen | - -Alle Zugriffe sind auf den `workspace/`-Ordner beschränkt (Path-Traversal-Schutz). - -### `backend/agent/servers/mcp_server_web_search.py` — WebSearchServer - -| Tool | Beschreibung | -|---|---| -| `web_search(query, max_results)` | DuckDuckGo-Suche, gibt formatierte Ergebnisse zurück | -| `fetch_page(url)` | Webseite abrufen und Text extrahieren (max. 4000 Zeichen) | - -SSRF-Schutz: Blockiert `localhost`, private IP-Ranges und nicht-HTTP/HTTPS-Schemata. - ---- - -## CLI-Test - -`run_agent.py` ermöglicht den Coding Agent direkt im Terminal zu testen ohne die Streamlit-App zu starten: +### 1. Repository klonen ```bash -python run_agent.py -# Aufgabe eingeben → Enter zum Genehmigen, Text zum Ablehnen, "stop" zum Abbrechen +git clone https://gitea.fhgr.ch/meulilivio/AISE1_Project.git +cd AISE1_Project +``` + +### 2. Virtuelle Umgebung aktivieren + +```bash +# Windows +.\.venv\Scripts\Activate.ps1 + +# macOS/Linux +source .venv/bin/activate +``` + +### 3. Abhängigkeiten installieren + +```bash +pip install -r requirements.txt +``` + +### 4. Umgebungsvariablen konfigurieren + +```bash +cp .env.example .env +# .env mit API-Keys befüllen +``` + +### 5. Applikation starten + +```bash +streamlit run frontend/app.py +``` + +### 6. Tests ausführen + +```bash +pytest tests/ -v +``` + +## Konfiguration: `mcp_server_config.json` + +Die Datei `backend/agent/mcp_server_config.json` definiert, welche MCP-Server der Agent starten soll. Jeder Eintrag enthält den Servernamen, den Startbefehl (`command`) und optionale Argumente (`args`) sowie Umgebungsvariablen (`env`): + +```json +{ + "FileSearchServer": { + "command": "py", + "args": ["servers/mcp_server_file_search.py"] + }, + "WebSearchServer": { + "command": "py", + "args": ["servers/mcp_server_web_search.py"], + "env": { "DDGS_API_KEY": "your_key_here" } + } +} +``` + +## Architektur + +``` +Frontend (Streamlit) ──► Backend Manager ──► AI API + │ + └──► Coding Agent ──► MCP-Adapter ──► MCP-Server + (Code / File / Web) +``` + +## Entwicklung + +```bash +git add . +git commit -m "Deine Nachricht" +git push origin main ``` diff --git a/READMEnew.md b/READMEnew.md index 080690f..e8a4a09 100644 --- a/READMEnew.md +++ b/READMEnew.md @@ -1,72 +1,21 @@ -# AISE AI Agent — Code Editor & Coding Assistant +# AISE AI Code Editor — Technische Dokumentation -Ein browserbasierter Code-Editor mit integriertem AI-Chat und autonomem Coding-Agent. Das Projekt kombiniert eine Streamlit-Oberfläche mit einem LLM-Backend und dem Model Context Protocol (MCP), um einen vollständigen AI-gestützten Entwicklungsworkflow zu ermöglichen. +AI-Supported Lightweight Code Editor built with Streamlit (AISE501 Spring 2026) + +Diese Datei enthält die ausführliche technische Dokumentation des Projekts. Für eine Kurzübersicht siehe `README.md`. --- -## Was kann das Projekt? +## Inhaltsverzeichnis -- **Code schreiben und bearbeiten** im Browser mit Syntax-Highlighting (Ace Editor) -- **Code direkt ausführen** und Output anzeigen, ohne die App zu verlassen -- **Mit einem AI-Assistenten chatten**, der den aktuell geöffneten Code als Kontext kennt -- **Fehler mit AI debuggen** — ein Klick schickt den Fehler + Code automatisch an den Chat -- **Einen autonomen Coding-Agent starten**, der selbstständig Aufgaben plant und umsetzt (Dateien lesen/schreiben, Code ausführen, im Web suchen) — jeder Schritt wird dem Benutzer zur Genehmigung vorgelegt - ---- - -## Voraussetzungen - -- Python 3.13 oder neuer -- pip -- Zugang zu einem OpenAI-kompatiblen LLM-Endpoint (z.B. FHGR Silicon Server) - ---- - -## Installation - -```bash -# 1. Repository klonen -git clone -cd AISE_AIAgent - -# 2. Virtuelle Umgebung erstellen und aktivieren -python -m venv .venv - -# Windows: -.venv\Scripts\activate -# macOS / Linux: -source .venv/bin/activate - -# 3. Abhängigkeiten installieren -pip install -r requirements.txt - -# 4. Umgebungsvariablen konfigurieren -copy .env.example .env # Windows -# cp .env.example .env # macOS/Linux -``` - -Dann `.env` öffnen und die Werte anpassen: - -```env -HOST=silicon.fhgr.ch # Hostname des LLM-Servers -PORT=7080 # Port des LLM-Servers -API_KEY=EMPTY # API-Key (EMPTY wenn kein Key benötigt) -MODEL=qwen3.5-35b-a3b # Modell-Name -``` - ---- - -## Starten - -```bash -# Streamlit Web-App starten (Hauptinterface) -streamlit run frontend/app.py - -# Coding Agent im Terminal testen (ohne Streamlit) -python run_agent.py -``` - -Nach `streamlit run frontend/app.py` öffnet sich die App automatisch im Browser unter `http://localhost:8501`. +1. [Projektstruktur](#projektstruktur) +2. [Frontend](#frontend) +3. [Backend Manager](#backend-manager) +4. [Backend Agent (MCP-System)](#backend-agent-mcp-system) +5. [MCP-Server-Konfiguration](#mcp-server-konfiguration) +6. [Tests](#tests) +7. [Setup](#setup) +8. [Architektur-Übersicht](#architektur-übersicht) --- @@ -74,308 +23,361 @@ Nach `streamlit run frontend/app.py` öffnet sich die App automatisch im Browser ``` AISE_AIAgent/ +├── frontend/ # Streamlit UI-Komponenten +│ ├── app.py # Haupteinstiegspunkt der Streamlit-App +│ ├── state.py # Session-State-Verwaltung +│ ├── sidebar.py # Datei-Navigation (Sidebar) +│ ├── editor.py # Code-Editor-Pane +│ └── chat.py # Chat-Interface │ -├── frontend/ # Gesamte Streamlit-Benutzeroberfläche -│ ├── app.py # Einstiegspunkt, App-Routing -│ ├── state.py # Session-State Initialisierung -│ ├── sidebar.py # Navigation + File Explorer -│ ├── editor.py # Code-Editor Ansicht -│ └── chat.py # Chat + Agent Mode Ansicht -│ -├── backend/ -│ ├── agent/ # Coding Agent Logik -│ │ ├── coding_agent.py # Agent Klasse (Plan→Act→Observe Loop) -│ │ ├── mcp_server_adapter.py # MCP-Client (verbindet Agent mit Servern) -│ │ ├── mcp_server_adapter_RAG.py -│ │ ├── mcp_server_config.json -│ │ └── servers/ # MCP-Server (laufen als eigene Prozesse) -│ │ ├── mcp_server_code_execution.py -│ │ ├── mcp_server_file_search.py -│ │ └── mcp_server_web_search.py +├── backend/ # Backend-Logik +│ ├── managers/ # Business-Logik für UI-Operationen +│ │ ├── file_manager.py # Datei-CRUD (lesen, schreiben, listen) +│ │ ├── chat_manager.py # AI-Chat-Verwaltung und -History +│ │ ├── system_prompter.py # System-Prompts und Kontext-Injektion +│ │ ├── search_manager.py # Web-Suche (DuckDuckGo) +│ │ ├── execution_engine.py # Code-Ausführung und Sandboxing +│ │ └── debug_logger.py # Logging, Fehlerbehandlung, Debug-Ausgaben │ │ -│ └── managers/ # Business-Logik Module -│ ├── chat_manager.py # LLM-API Kommunikation + Chat-History -│ ├── file_manager.py # Datei/Ordner-Operationen im Workspace -│ ├── execution_engine.py # Code-Ausführung via Subprocess -│ ├── system_prompter.py # System-Prompt Generierung -│ └── debug_logger.py # Einfacher In-Memory Logger -│ └── search_manager.py # Einfacher In-Memory Such-Manager -├── tests/ -| ├── conftest.py -| ├── test_file_manager.py # Unit-Tests für FileManager -| ├── test_chat_manager.py # Unit-Tests für ChatManager -| ├── test_execution_engine.py # Unit-Tests für ExecutionEngine -| ├── test_coding_agent.py # Unit-Tests für CodingAgent -| ├── test_search_manager.py # Unit-Tests für SearchManager -| ├── test_debug_logger.py # Unit-Tests für DebugLogger -| ├── test_mcp_server_code_execution.py -| ├── test_mcp_server_web_search.py -| ├── test_system_prompter.py -| └── test_mcp_server_file_search.py -| -├── workspace/ # Arbeitsverzeichnis (Dateien des Editors/Agents) -└── .env.example # Vorlage für Umgebungsvariablen +│ └── agent/ # Autonomes AI-Agent-System (MCP-basiert) +│ ├── coding_agent.py # Haupt-Agent-Loop (Plan-Act-Observe) +│ ├── mcp_server_adapter.py # MCP-Adapter: verbindet Agent mit MCP-Servern +│ ├── mcp_server_adapter_RAG.py # MCP-Adapter mit RAG-basierter Tool-Auswahl +│ ├── mcp_server_config.json # Konfiguration der MCP-Server (Startbefehle) +│ └── servers/ # MCP-Server-Implementierungen +│ ├── mcp_server_code_execution.py # Tool: Python-Code ausführen +│ ├── mcp_server_file_search.py # Tool: Dateien suchen und lesen +│ └── mcp_server_web_search.py # Tool: Web-Suche via DuckDuckGo +│ +├── tests/ # Unit-Tests (pytest) +│ ├── conftest.py # Globale Test-Fixtures und MCP-Mocks +│ ├── test_file_manager.py +│ ├── test_chat_manager.py +│ ├── test_execution_engine.py +│ ├── test_coding_agent.py +│ ├── test_debug_logger.py +│ ├── test_system_prompter.py +│ ├── test_mcp_server_code_execution.py +│ ├── test_mcp_server_file_search.py +│ └── test_mcp_server_web_search.py +│ +├── workspace/ # Agent-Sandbox (isoliertes Arbeitsverzeichnis) +├── run_agent.py # CLI-Einstiegspunkt für den Coding-Agent +└── .env.example # Vorlage für Umgebungsvariablen ``` --- ## Frontend -### `frontend/app.py` — Einstiegspunkt der App +Das Frontend besteht aus Streamlit-Komponenten, die zusammen eine interaktive Code-Editor-Oberfläche bilden. -Dieser File ist der Startpunkt der gesamten Streamlit-Applikation. Er wird direkt mit `streamlit run` aufgerufen und übernimmt drei Aufgaben: Er setzt das globale Seitenlayout (Titel, breites Layout, minimales CSS-Padding), ruft `init_state()` auf um alle Session-State-Variablen zu initialisieren, und leitet den Benutzer basierend auf der Sidebar-Auswahl entweder zur Editor-Ansicht oder zur Chat-Ansicht weiter. +### `app.py` +Haupteinstiegspunkt der Applikation. Orchestriert das Layout und initialisiert alle UI-Komponenten (Sidebar, Editor, Chat). + +### `state.py` +Zentralisierte Verwaltung des Streamlit Session-State. Stellt sicher, dass alle Komponenten denselben Zustand (geöffnete Datei, Chat-History, Agent-Status) teilen. + +### `sidebar.py` +Datei-Browser und Projekt-Navigation. Erlaubt das Durchsuchen des Workspaces und das Öffnen von Dateien im Editor. + +### `editor.py` +Code-Editor-Pane mit Syntax-Highlighting. Ermöglicht das Bearbeiten und Speichern von Code-Dateien direkt im Browser. + +### `chat.py` +Chat-Interface für den KI-Assistenten. Zeigt die Konversations-History und ermöglicht Eingaben an das AI-Modell. --- -### `frontend/state.py` — Session State Verwaltung +## Backend Manager -Streamlit rendert die gesamte App bei jeder Benutzerinteraktion neu. Um Daten zwischen diesen Reruns zu erhalten (offene Dateien, Chat-Verlauf, Agent-Status etc.), nutzt Streamlit `session_state`. Dieser File definiert und initialisiert alle verwendeten Keys mit ihren Standardwerten an einem zentralen Ort — damit kein anderer Teil der App auf einen nicht-existierenden Key trifft. +Die Manager-Klassen kapseln die Business-Logik und werden direkt vom Frontend aufgerufen. -**Wichtige State-Keys:** -- `open_files` — Liste aller aktuell geöffneten Dateipfade (bestimmt die Tab-Reihenfolge) -- `files_content` — Dict `{Dateipfad: aktueller Editorinhalt}` (ungespeicherte Änderungen inklusive) -- `active_file` — Absoluter Pfad der aktuell aktiven Datei -- `chat_history` — Flache Liste aller Chat-Nachrichten `[{role, content}, ...]` -- `agent_mode` — Boolean ob der Agent Mode aktiv ist -- `agent_status` — Aktueller Agent-Zustand: `"idle"` | `"waiting_approval"` | `"done"` -- `agent_log` — Liste aller abgeschlossenen Agent-Schritte -- `agent_pending_action` — Die vom Agent vorgeschlagene, noch nicht ausgeführte Aktion +### `file_manager.py` +Stellt CRUD-Operationen auf dem Workspace-Verzeichnis bereit: +- Dateien lesen, schreiben, umbenennen, löschen +- Verzeichnisstruktur auflisten +- Sichere Pfadvalidierung (verhindert Path-Traversal) + +### `chat_manager.py` +Verwaltet AI-Chat-Interaktionen: +- Aufbau und Verwaltung der Chat-History +- Senden von Nachrichten an das AI-Modell +- Formatierung von System- und User-Nachrichten + +### `system_prompter.py` +Generiert kontextreiche System-Prompts für den AI-Assistenten: +- Injektion von aktuellem Dateiinhalt als Kontext +- Steuerung des AI-Verhaltens (Coding-Assistent-Persona) + +### `execution_engine.py` +Führt Python-Code sicher aus: +- Subprocess-basierte Code-Ausführung +- Timeout-Schutz und Output-Capture +- Fehler- und Exception-Handling + +### `debug_logger.py` +Logging und Fehler-Tracking: +- Formatierte Log-Ausgaben für Debugging +- Fehler-Aggregation für die UI-Darstellung + +### `search_manager.py` +Web-Suche für den KI-Assistenten via DuckDuckGo: +- Nutzt die `ddgs`-Bibliothek (DuckDuckGo Search) für API-freie Websuche +- Gibt strukturierte Suchergebnisse zurück (Titel, URL, Snippet) +- Wird vom Chat-Manager aufgerufen, wenn der Assistent externe Dokumentation oder Code-Beispiele benötigt +- Keine API-Key-Konfiguration notwendig (da DuckDuckGo öffentlich zugänglich ist) --- -### `frontend/sidebar.py` — Navigation & File Explorer +## Backend Agent (MCP-System) -Die Sidebar ist in zwei Bereiche aufgeteilt: +Der Agent ist ein autonomes System, das komplexe Coding-Aufgaben selbstständig löst. Er kommuniziert mit externen Tool-Servern über das **Model Context Protocol (MCP)**. -**Navigation:** Ein Radio-Button schaltet zwischen "Code Editor" und "Chat with AI Assistant" um. Die aktuelle Auswahl wird in `session_state.radio_interface_options` gespeichert und von `app.py` ausgewertet. +### `coding_agent.py` +Implementiert den Plan-Act-Observe-Loop: +1. **Plan**: Das AI-Modell wählt das nächste Tool und Argumente +2. **Act**: Das Tool wird via MCP-Adapter aufgerufen (nach User-Bestätigung) +3. **Observe**: Das Ergebnis wird in die Message-History eingefügt +4. Der Loop wiederholt sich bis zur Fertigstellung oder einem `done`-Tool-Aufruf -**File Explorer:** Ein interaktiver Dateibaum zeigt den gesamten `workspace/`-Ordner an. Implementiert mit `streamlit-arborist`, das einen klickbaren Baum mit Ordner-Icons rendert. Ein Klick auf eine Datei öffnet sie im Editor und wechselt automatisch zur Editor-Ansicht. Ein Klick auf einen Ordner zeigt eine Aktionsleiste mit Buttons zum Erstellen von Dateien/Unterordnern und zum Löschen des Ordners. +Wichtige Klassen und Funktionen: +- `CodingAgent`: Haupt-Klasse mit `start_task()`, `propose_next_action()`, `approve()`, `reject()` +- `truncate_result()`: Kürzt lange Tool-Outputs bevor sie in die History gehen +- `trim_messages()`: Entfernt alte Turns aus der History wenn das Kontextfenster voll wird +- `_strip_code_fences()`: Bereinigt Markdown-Fences aus LLM-JSON-Antworten -**Modale Dialoge** (via `@st.dialog`): -- `_add_file_dialog` — Neuen Dateinamen eingeben und Datei erstellen -- `_add_folder_dialog` — Neuen Ordnernamen eingeben und Ordner erstellen -- `_rename_file_dialog` — Datei umbenennen (Extension wird automatisch beibehalten) -- `_delete_file_dialog` — Löschbestätigung für Dateien -- `_delete_folder_dialog` — Löschbestätigung für Ordner inkl. Inhalt +Konstanten: `MAX_ITERATIONS`, `MAX_RESULT_LENGTH`, `MAX_HISTORY_CHARS` + +### `mcp_server_adapter.py` +Verbindet den Coding-Agent mit den MCP-Tool-Servern: +- Liest `mcp_server_config.json` und startet die konfigurierten Server als Subprozesse +- Baut MCP-Sessions via `stdio_client` auf +- Registriert alle verfügbaren Tools aus allen Servern in einem zentralen `tool_registry` +- Delegiert Tool-Aufrufe an den richtigen Server via `call_tool()` + +Hauptmethoden: +- `initialize_all_servers()`: Startet alle Server und baut Sessions auf +- `get_all_tools()`: Gibt alle registrierten Tool-Definitionen zurück +- `call_tool(tool_name, arguments)`: Führt ein Tool auf dem zuständigen Server aus + +### `mcp_server_adapter_RAG.py` +Erweiterter MCP-Adapter mit semantischer Tool-Auswahl via Retrieval-Augmented Generation (RAG): + +**Motivation**: Bei vielen MCP-Tools kann das LLM-Kontextfenster überfüllt werden, wenn alle Tool-Definitionen mitgesendet werden. Der RAG-Adapter löst dies durch semantische Vorauswahl. + +**Funktionsweise**: +1. Beim Initialisieren werden alle Tool-Beschreibungen mit `SentenceTransformer('all-MiniLM-L6-v2')` in Embeddings umgewandelt +2. Bei jedem Agent-Schritt wird der aktuelle Task als Query kodiert +3. Cosine-Similarity zwischen Query- und Tool-Embeddings bestimmt die `top_k` relevantesten Tools +4. Nur diese Tools werden dem LLM als verfügbare Aktionen präsentiert + +Hauptmethoden: +- `initialize_all_sessions()`: Startet Server, baut Sessions auf, erstellt Embedding-Index +- `get_relevant_tools(query, top_k=5)`: Gibt die `top_k` semantisch ähnlichsten Tools zurück +- `call_tool(tool_name, arguments)`: Findet den zuständigen Server und führt das Tool aus +- `shutdown_all_sessions()`: Schliesst alle offenen MCP-Sessions sauber + +Abhängigkeit: `sentence-transformers`, `numpy` + +**Hinweis**: Diese Klasse befindet sich noch in der Entwicklung (Work in Progress). Es gibt bekannte Bugs (z.B. Tippfehler `commanf` statt `command`, falsche Verwendung von `result.get()` vs. `result.tools`). --- -### `frontend/editor.py` — Code-Editor +## MCP-Server-Konfiguration -Der Code-Editor ist die zentrale Arbeitsfläche für das direkte Bearbeiten von Dateien. +### Format: `mcp_server_config.json` -**Ace Editor (`streamlit-ace`):** Jede offene Datei wird in einem Tab mit dem Ace-Editor angezeigt. Der Editor erkennt die Dateiendung automatisch und stellt das passende Syntax-Highlighting ein (Python, JavaScript, HTML, CSS, JSON, YAML, LaTeX, Bash). Das Theme ist "Monokai". `auto_update=True` bedeutet, dass Änderungen sofort in `session_state.files_content` landen — ohne expliziten Submit. +Die Datei `backend/agent/mcp_server_config.json` definiert, welche MCP-Server der Adapter starten soll. Das Format ist ein JSON-Objekt, wobei jeder Key ein frei wählbarer Servername ist: -**Tab-Verwaltung:** Jede offene Datei erscheint als Tab. Wenn eine Datei aus dem File Explorer geöffnet wird, springt ein JavaScript-Snippet automatisch auf den richtigen Tab (da `st.tabs` keinen programmatischen Tab-Wechsel unterstützt). - -**Aktions-Buttons pro Datei:** -- **Save Changes** — Schreibt den aktuellen Editorinhalt auf Disk -- **Close File** — Entfernt die Datei aus den offenen Tabs -- **Rename File** — Öffnet Rename-Dialog -- **Delete File** — Öffnet Lösch-Bestätigungsdialog -- **▶ Run Code** — Führt die Datei aus (Python via `py`, LaTeX via `pdflatex`) - -**Ausführungs-Output:** Nach dem Ausführen erscheinen stdout, stderr und der Exit-Code unterhalb des Editors. Bei einem Fehler erscheint zusätzlich der Button **"🐛 Debug with AI"** — dieser baut automatisch eine Fehlernachricht zusammen (Fehlertext + kompletter Code) und schickt sie an den Chat-Assistenten. - ---- - -### `frontend/chat.py` — Chat & Agent Mode - -Dieser File enthält zwei grundlegend verschiedene Interfaces, die über einen Toggle umgeschaltet werden. - -#### Normaler Chat - -Ein klassischer Multi-Turn-Chatbot. Bei der ersten Nachricht wird automatisch ein System-Prompt generiert. Falls eine Datei im Editor geöffnet ist und "Include current file as context" aktiviert ist, wird der Dateiinhalt in den System-Prompt eingebettet — der AI-Assistent "sieht" also den Code und kann gezielt darauf eingehen. - -Bei jeder Folgenachricht wird der System-Prompt aktualisiert falls eine andere Datei aktiv ist. Das Modell, die maximale Tokenzahl und ein eigener System-Prompt können in einem aufklappbaren Settings-Panel konfiguriert werden. Der "Clear Chat" Button öffnet einen Bestätigungsdialog. - -#### Agent Mode - -Der Agent Mode verwandelt den Chat in ein Step-by-Step Kontrollinterface für den autonomen `CodingAgent`. - -**Ablauf:** -1. Benutzer gibt eine Aufgabe ein (z.B. "Schreibe eine Funktion die eine Liste sortiert und speichere sie als sorted.py") -2. Der Agent analysiert die Aufgabe und schlägt einen ersten Schritt vor (z.B. `write_new_file` mit dem generierten Code) -3. Die UI zeigt den Gedankengang des Agents ("Thought"), das gewählte Tool und die Argumente an -4. Benutzer klickt **Approve** → Aktion wird ausgeführt, nächster Schritt wird vorgeschlagen -5. Oder **Reject** → Benutzer gibt Feedback ein, Agent plant neu ohne die Aktion auszuführen -6. Oder **Abort Task** → Agent wird sofort gestoppt -7. Nach Abschluss kann eine Follow-up Frage gestellt werden ohne den Kontext zu verlieren - -Der **Agent Log** zeigt alle abgeschlossenen Schritte in einem aufklappbaren Bereich. - ---- - -## Backend — Managers - -### `backend/managers/chat_manager.py` — ChatManager - -Kapselt die gesamte Kommunikation mit dem LLM. Verbindet sich mit einem OpenAI-kompatiblen REST-Endpoint (`/v1/chat/completions`) dessen Adresse und Key aus der `.env` gelesen werden. - -Der Chat-Verlauf wird als Liste von `{role, content}`-Dicts in-memory gehalten. Bei jedem `send_message`-Aufruf wird die vollständige History mitgeschickt, sodass das Modell immer den gesamten Gesprächskontext kennt. - -| Methode | Beschreibung | -|---|---| -| `send_message(user_message)` | Nachricht zur History hinzufügen, API-Call machen, Antwort zurückgeben und in History speichern | -| `add_message(role, content)` | Nachricht direkt zur History hinzufügen (z.B. für System-Prompt) | -| `get_history()` | Kopie der aktuellen History zurückgeben | -| `clear_history()` | Gesamten Verlauf löschen (neuer Chat) | - ---- - -### `backend/managers/file_manager.py` — FileManager - -Abstrahiert alle Dateioperationen und stellt sicher, dass jeder Zugriff innerhalb des `workspace/`-Verzeichnisses bleibt. Jede Methode löst den angegebenen Pfad zu einem absoluten Pfad auf und prüft mit `startswith(workspace.resolve())` ob der Pfad im erlaubten Bereich liegt — damit sind Path-Traversal-Angriffe wie `../../etc/passwd` ausgeschlossen. - -| Methode | Beschreibung | -|---|---| -| `create_file(relative_path, name)` | Neue leere Datei erstellen. Ohne Extension wird `.txt` ergänzt. Schlägt fehl wenn Datei existiert. | -| `create_folder(relative_path, name)` | Neuen Ordner erstellen. Schlägt fehl wenn Ordner existiert. | -| `read_file(path)` | Dateiinhalt als String lesen. Gibt leeren String bei Fehler zurück. | -| `save_file(path, content)` | Datei mit neuem Inhalt überschreiben (erstellt falls nicht vorhanden). | -| `rename_file(old_path, new_name)` | Datei umbenennen. Die Dateiendung wird immer vom Original übernommen. | -| `delete_file(relative_path)` | Einzelne Datei löschen. | -| `delete_folder(relative_path)` | Ordner und gesamten Inhalt rekursiv löschen. | -| `get_file_tree()` | Gesamten Workspace als verschachteltes Dict zurückgeben: Ordner als `{name: dict}`, Dateien als `{name: None}`. | - ---- - -### `backend/managers/execution_engine.py` — ExecutionEngine - -Führt Dateien aus dem Editor als Subprocess aus. Die Datei wird immer aus ihrem eigenen Verzeichnis heraus gestartet (`cwd=file.parent`), damit relative Imports und Pfade korrekt funktionieren. - -Unterstützte Dateitypen: -- **Python (`.py`)** → `py ` (nutzt den Windows Python Launcher) -- **LaTeX (`.tex`)** → `pdflatex -interaction=nonstopmode ` - -Timeout: 30 Sekunden. Gibt immer ein Dict `{stdout, stderr, rc}` zurück. - ---- - -### `backend/managers/system_prompter.py` — SystemPrompter - -Baut den System-Prompt für den normalen Chat zusammen. Ohne Datei-Kontext enthält er nur eine allgemeine Beschreibung des AI-Assistenten. Mit Datei-Kontext wird der Dateiname und der Inhalt (max. 4000 Zeichen, danach abgeschnitten) in XML-ähnliche Tags eingebettet: - -``` - - -def fib(n): ... - - +```json +{ + "ServerName": { + "command": "py", + "args": ["servers/mcp_server_datei.py"], + "env": { + "API_KEY": "optional_key" + } + } +} ``` -Das Modell wird angewiesen sich auf diese Datei zu beziehen wenn es Fragen zum Code beantwortet. +| Feld | Pflicht | Beschreibung | +|-----------|---------|--------------| +| `command` | Ja | Ausführbares Programm (z.B. `py`, `python3`, `node`) | +| `args` | Ja | Argumente als Array (Pfad zum Server-Script) | +| `env` | Nein | Umgebungsvariablen für den Serverprozess | + +### Aktuelle Server + +```json +{ + "FileSearchServer": { + "command": "py", + "args": ["servers/mcp_server_file_search.py"] + }, + "WebSearchServer": { + "command": "py", + "args": ["servers/mcp_server_web_search.py"], + "env": { "DDGS_API_KEY": "your_ddgs_api_key_here" } + }, + "CodeExecutionServer": { + "command": "py", + "args": ["servers/mcp_server_code_execution.py"] + } +} +``` + +### Neuen MCP-Server hinzufügen + +1. Neues Server-Script in `backend/agent/servers/` erstellen (MCP-konformes Python-Script) +2. Eintrag in `mcp_server_config.json` ergänzen: + ```json + "MeinNeuerServer": { + "command": "py", + "args": ["servers/mcp_server_mein_tool.py"] + } + ``` +3. Der Adapter erkennt den neuen Server beim nächsten Start automatisch und registriert seine Tools --- -### `backend/managers/debug_logger.py` — DebugLogger +## Tests -Einfacher In-Memory-Logger der Ausführungsmeldungen für den Code-Editor speichert. Wird von `editor.py` genutzt um den Status einer Code-Ausführung (`log()`, `log_error()`, `clear()`) zu protokollieren. - ---- - -## Backend — Coding Agent - -### `backend/agent/coding_agent.py` — CodingAgent - -Das Herzstück des autonomen Agents. Implementiert den **Plan → Act → Observe → Fix → Done** Loop. - -**Wie der Loop funktioniert:** -1. `start_task(task)` initialisiert den Agenten mit dem System-Prompt (enthält Beschreibungen aller verfügbaren MCP-Tools) und der Aufgabe -2. `propose_next_action()` schickt den bisherigen Konversationsverlauf an das LLM. Das Modell antwortet immer mit einem JSON-Objekt `{"thought": "...", "tool": "...", "arguments": {...}}`. Die Antwort wird geparsed und als `pending_action` gespeichert — aber **noch nicht ausgeführt** -3. `approve()` führt die pending_action aus, fügt das Resultat als User-Nachricht zur History hinzu und ruft sofort `propose_next_action()` auf -4. `reject(feedback)` verwirft die pending_action ohne sie auszuführen und injiziert das Feedback als User-Nachricht -5. Wenn das LLM `"done"` als Tool wählt, setzt der Agent `is_done = True` - -**Robustheit:** LLM-Antworten die kein valides JSON enthalten werden durch `extract_json()` und `_repair_json_strings()` bereinigt (entfernt Markdown-Fences, repariert unescapte Newlines in Strings). Wenn die History das Limit von 80'000 Zeichen überschreitet, werden ältere Nachrichten entfernt und ein Erinnerungs-Hinweis injiziert. - -| Methode | Beschreibung | -|---|---| -| `start_task(task)` | Agent neu initialisieren, System-Prompt + Aufgabe setzen | -| `propose_next_action()` | LLM-Aufruf → JSON-Antwort parsen → als `pending_action` speichern | -| `approve()` | `pending_action` ausführen, Resultat zur History hinzufügen, nächste Aktion vorschlagen | -| `reject(feedback)` | `pending_action` verwerfen, Feedback injizieren | -| `follow_up(question)` | Nach Abschluss: Folgefrage stellen ohne Kontext zu verlieren | - ---- - -### `backend/agent/mcp_server_adapter.py` — MCPToolAdapter - -Der Adapter ist die Brücke zwischen dem `CodingAgent` und den MCP-Servern. Er liest beim Start die Konfigurationsdatei `mcp_server_config.json`, verbindet sich zu jedem Server, fragt dessen Tool-Liste ab und speichert alle Tools in einer internen Registry. - -Bei jedem `call_tool`-Aufruf öffnet der Adapter eine neue `stdio`-Verbindung zum zuständigen Server, führt das Tool aus und schliesst die Verbindung wieder. Das heisst: Die Server laufen nicht permanent, sondern werden für jeden Aufruf frisch gestartet. Das macht das System robuster (kein veralteter State in einem Server) aber etwas langsamer. - -| Methode | Beschreibung | -|---|---| -| `initialize_all_servers()` | Alle konfigurierten Server starten, Tool-Liste abfragen, in Registry speichern | -| `call_tool(tool_name, arguments)` | Passenden Server für das Tool finden, Verbindung aufbauen, Tool aufrufen, Ergebnis zurückgeben | -| `get_all_tools()` | Komplette Tool-Registry zurückgeben | - ---- - -## MCP-Server - -Die drei MCP-Server sind eigenständige Python-Prozesse die über das `stdio`-Transportprotokoll kommunizieren. Sie werden vom Adapter gestartet und stellen dem Coding Agent Tools zur Verfügung. - ---- - -### `backend/agent/servers/mcp_server_code_execution.py` — CodeExecutionServer - -Ermöglicht dem Agent das sichere Ausführen von Python-Code. Bevor Code ausgeführt wird, durchläuft er eine **zweistufige Sicherheitsprüfung**: - -1. **Statische AST-Analyse** (`check_code_safety`): Der Code wird mit Pythons `ast`-Modul geparst. Jeder Import-Node und jeder Funktionsaufruf wird gegen Blocklisten geprüft. Blockierte Imports umfassen u.a. `os`, `sys`, `subprocess`, `socket`, `pickle`. Blockierte Builtins umfassen `exec`, `eval`, `open`, `compile`. - -2. **String-Suche nach verbotenen Sequenzen**: Zusätzlich wird der Code-String direkt nach gefährlichen Mustern durchsucht (`../`, `os.`, `sys.`, `subprocess.` etc.). - -Erst wenn beide Prüfungen bestanden sind, wird der Code via `subprocess.run([sys.executable, "-c", code], stdin=subprocess.DEVNULL, ...)` ausgeführt. `stdin=subprocess.DEVNULL` ist entscheidend: Da der MCP-Server über asyncio-verwaltetes `stdio` läuft, würde der Kind-Prozess sonst stdin erben und blockieren. - -| Tool | Beschreibung | -|---|---| -| `run_python_sandboxed(code)` | Code nach Sicherheitsprüfung ausführen. Gibt stdout+stderr zurück (max. 3000 Zeichen). Timeout: 45s. | -| `python_code_validation(code)` | Nur prüfen (Syntax + Sicherheit), nicht ausführen. | -| `lint_code(code)` | Pyflakes-Analyse: ungenutzte Imports, undefinierte Variablen, Syntax-Fehler. | -| `analyse_structure(code)` | Imports, Klassen (mit Methoden) und Top-Level-Funktionen als strukturierte Zusammenfassung. | - ---- - -### `backend/agent/servers/mcp_server_file_search.py` — FileSearchServer - -Gibt dem Agent Lese- und Schreibzugriff auf den `workspace/`-Ordner. Alle Pfade werden über `_safe_path()` gegen Path-Traversal validiert — ein Zugriff ausserhalb des Workspace ist nicht möglich. - -| Tool | Beschreibung | -|---|---| -| `list_files()` | Alle Dateien im Workspace rekursiv auflisten (ohne `__pycache__`). | -| `get_file_tree(dir_path)` | Verzeichnisstruktur als formatierter Text (ähnlich `tree`-Befehl). | -| `search_files(query)` | Dateien deren Name oder Inhalt den Suchbegriff enthält (case-insensitive). | -| `read_file(path)` | Vollständigen Inhalt einer Datei lesen. | -| `write_new_file(path, content)` | Neue Datei erstellen und Inhalt schreiben. Bestehende Dateien können **nicht** überschrieben werden. | -| `create_new_directory(path)` | Neues Verzeichnis im Workspace erstellen. | - ---- - -### `backend/agent/servers/mcp_server_web_search.py` — WebSearchServer - -Gibt dem Agent Zugriff auf das Internet. Enthält einen SSRF-Schutz der verhindert, dass der Agent interne Adressen abruft. - -**SSRF-Schutz** (`_validate_url`): Nur `http://` und `https://`-URLs sind erlaubt. Hostnamen wie `localhost`, `127.0.0.1`, `0.0.0.0`, `169.254.169.254` (AWS Metadata) sowie alle privaten IP-Ranges (`10.x`, `172.16-31.x`, `192.168.x`) sind blockiert. - -| Tool | Beschreibung | -|---|---| -| `web_search(query, max_results)` | DuckDuckGo-Suche. Gibt Titel, URL und Snippet für jedes Ergebnis zurück (Standard: 5 Ergebnisse). | -| `fetch_page(url)` | URL abrufen, HTML parsen, Fliesstext extrahieren (max. 4000 Zeichen). | - ---- - -## CLI-Test mit `run_agent.py` - -Für schnelles Testen des Coding Agents ohne die Streamlit-App: +### Tests ausführen ```bash -python run_agent.py +# Alle Tests ausführen +pytest tests/ -v + +# Einzelnes Test-Modul ausführen +pytest tests/test_coding_agent.py -v + +# Tests mit Kurzausgabe +pytest tests/ ``` -Das Script startet eine interaktive Konsolen-Session: -- **Aufgabe eingeben** → Agent startet -- **Enter drücken** → Vorgeschlagene Aktion genehmigen und ausführen -- **Text eingeben + Enter** → Feedback geben, Agent plant neu -- **`stop` eingeben** → Abbrechen +### Teststruktur + +Die Tests liegen in `tests/` und folgen dem Muster `test_.py`. + +#### `conftest.py` +Globale Pytest-Konfiguration. Patcht den `MCPToolAdapter` auf `sys.modules`-Ebene, bevor irgendein Test-Modul importiert wird. Dadurch werden beim Import von `coding_agent` keine echten MCP-Subprozesse gestartet. Der Mock-Adapter liefert sofort leere Ergebnisse zurück. + +#### Was wird getestet + +| Test-Datei | Getestetes Modul | Schwerpunkt | +|---|---|---| +| `test_file_manager.py` | `backend/managers/file_manager.py` | Datei-CRUD, Pfad-Validierung | +| `test_chat_manager.py` | `backend/managers/chat_manager.py` | Chat-History, Nachrichtenformatierung | +| `test_execution_engine.py` | `backend/managers/execution_engine.py` | Code-Ausführung, Timeouts, Fehlerbehandlung | +| `test_system_prompter.py` | `backend/managers/system_prompter.py` | Prompt-Generierung, Kontext-Injektion | +| `test_debug_logger.py` | `backend/managers/debug_logger.py` | Log-Formatierung, Fehler-Aggregation | +| `test_coding_agent.py` | `backend/agent/coding_agent.py` | Agent-Loop, Tool-Dispatch, History-Trimming | +| `test_mcp_server_code_execution.py` | `backend/agent/servers/mcp_server_code_execution.py` | MCP Code-Execution-Tool | +| `test_mcp_server_file_search.py` | `backend/agent/servers/mcp_server_file_search.py` | MCP Datei-Such-Tool | +| `test_mcp_server_web_search.py` | `backend/agent/servers/mcp_server_web_search.py` | MCP Web-Such-Tool | + +#### Testklassen in `test_coding_agent.py` + +- **`TestTruncateResult`**: Prüft, dass lange Tool-Outputs korrekt gekürzt werden +- **`TestTrimMessages`**: Prüft, dass alte History-Turns entfernt werden wenn der Kontext zu gross wird; System-Message und Original-Task bleiben immer erhalten +- **`TestStripCodeFences`**: Prüft, dass Markdown-Codeblöcke aus LLM-Antworten entfernt werden +- **`TestCodingAgentInit`**: Prüft initialen Zustand und `start_task()`-Reset-Verhalten +- **`TestProposeNextAction`**: Prüft den API-Aufruf-Zyklus mit gemockter API; testet Fehler-Handling (JSON-Parse-Fehler, API-Exceptions, Max-Iterations) +- **`TestApprove`**: Prüft `approve()` mit gemocktem `dispatch_tool`; testet Tool-Ergebnis-Injektion und Error-Replan-Tagging +- **`TestReject`**: Prüft, dass `reject()` das Feedback korrekt in die History injiziert und kein Tool ausführt + +#### Test-Konventionen + +- MCP-Server werden in Tests **nicht** als echte Subprozesse gestartet (via `conftest.py`-Mock) +- Streamlit-Aufrufe werden mit `patch("modul.st")` gemockt +- Dateisystem-Tests nutzen `tmp_path` (pytest-Fixture) für isolierte temporäre Verzeichnisse +- Async-Tests verwenden `@pytest.mark.asyncio` (benötigt `pytest-asyncio`) + +--- + +## Setup + +### 1. Repository klonen + +```bash +git clone https://gitea.fhgr.ch/meulilivio/AISE1_Project.git +cd AISE1_Project +``` + +### 2. Virtuelle Umgebung aktivieren + +```bash +# Windows +.\.venv\Scripts\Activate.ps1 + +# macOS/Linux +source .venv/bin/activate +``` + +### 3. Abhängigkeiten installieren + +```bash +pip install -r requirements.txt +``` + +### 4. Umgebungsvariablen konfigurieren + +```bash +cp .env.example .env +# .env mit API-Keys befüllen +``` + +### 5. Applikation starten + +```bash +streamlit run frontend/app.py +``` + +### 6. Tests ausführen + +```bash +pytest tests/ -v +``` + +--- + +## Architektur-Übersicht + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Frontend (Streamlit) │ +│ app.py → sidebar.py / editor.py / chat.py │ +│ │ │ +│ state.py (Session-State) │ +└──────────────┬──────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Backend Manager │ +│ FileManager / ChatManager / SystemPrompter / │ +│ SearchManager / ExecutionEngine / DebugLogger │ +└──────────────┬──────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Coding Agent (backend/agent/) │ +│ coding_agent.py ←→ mcp_server_adapter.py │ +│ │ │ +│ mcp_server_config.json │ +│ │ │ +│ ┌───────────────┼───────────────┐ │ +│ ▼ ▼ ▼ │ +│ mcp_server_file_search mcp_server_web mcp_server_code │ +│ │ +│ (Optional: mcp_server_adapter_RAG.py für semantische │ +│ Tool-Auswahl via Sentence Transformers) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ workspace/ │ +│ Isoliertes Sandbox-Verzeichnis für Agent-Dateien │ +└─────────────────────────────────────────────────────────────────┘ +```