2026-05-26 06:31:02 +02:00

18 KiB

AISE AI Code Editor — Technische Dokumentation

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.


Inhaltsverzeichnis

  1. Projektstruktur
  2. Frontend
  3. Backend Manager
  4. Backend Agent (MCP-System)
  5. MCP-Server-Konfiguration
  6. Tests
  7. Setup
  8. Architektur-Übersicht

Projektstruktur

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
│
├── 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

Frontend

Das Frontend besteht aus Streamlit-Komponenten, die zusammen eine interaktive Code-Editor-Oberfläche bilden.

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.


Backend Manager

Die Manager-Klassen kapseln die Business-Logik und werden direkt vom Frontend aufgerufen.

file_manager.py

Stellt CRUD-Operationen auf dem Workspace-Verzeichnis bereit:

  • Dateien lesen, schreiben, umbenennen, löschen
  • Verzeichnisstruktur auflisten
  • Sichere Pfadvalidierung (verhindert Path-Traversal)

Designentscheidung — list_files() vs. get_file_tree(): Die Projektspezifikation nennt list_files() als FileManager-Methode. Im vorliegenden Design wurde bewusst get_file_tree() implementiert, da das Frontend eine verschachtelte Baumstruktur benötigt (für den interaktiven File Explorer in der Sidebar). Eine flache Liste würde die Navigation nicht unterstützen. Für den Agent Mode übernimmt der MCP-Server mcp_server_file_search.py die Dateisuche — die Funktionalität ist damit im System vorhanden, nur architektonisch sauber getrennt.

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

Designentscheidung — Fehler-Output im normalen Chat: Laufzeitfehler und stderr-Output werden im normalen Chat bewusst nicht automatisch in den Chat-Kontext injiziert. Stattdessen gibt es den "Debug with AI"-Button im Editor, über den der User selbst entscheidet wann er die AI einschalten möchte. Dies verhindert, dass die Chat-History mit ungewollten Fehlermeldungen geflutet wird. Im Agent Mode wird dies anders gelöst: dort landet jeder Execution-Fehler automatisch als Observation im Plan-Act-Observe-Loop und der Agent replant ohne User-Eingriff.

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
  • format_debug_output(output) formatiert den Execution-Output (stdout, stderr, return_code) in einen einheitlichen String für die UI-Anzeige und den AI-Chat-Kontext

Designentscheidung — log_error() nicht implementiert: Die Projektspezifikation nennt log_error() als DebugLogger-Methode. Diese wurde bewusst nicht als separate Methode implementiert, da Python's eingebautes logging-Modul diese Funktionalität mit logger.error() bereits vollständig abdeckt. Im gesamten Projekt wird konsistent logger = get_logger(__name__) gefolgt von logger.error(...) verwendet — eine eigene Wrapper-Methode wäre toter Code ohne Mehrwert.

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)

Backend Agent (MCP-System)

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).

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

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

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).


MCP-Server-Konfiguration

Format: mcp_server_config.json

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:

{
  "ServerName": {
    "command": "py",
    "args": ["servers/mcp_server_datei.py"],
    "env": {
      "API_KEY": "optional_key"
    }
  }
}
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

{
  "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:
    "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

Tests

Tests ausführen

# Alle Tests ausführen
pytest tests/ -v

# Einzelnes Test-Modul ausführen
pytest tests/test_coding_agent.py -v

# Tests mit Kurzausgabe
pytest tests/

Teststruktur

Die Tests liegen in tests/ und folgen dem Muster test_<modulname>.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

git clone https://gitea.fhgr.ch/meulilivio/AISE1_Project.git
cd AISE1_Project

2. Virtuelle Umgebung aktivieren

# Windows
.\.venv\Scripts\Activate.ps1

# macOS/Linux
source .venv/bin/activate

3. Abhängigkeiten installieren

pip install -r requirements.txt

4. Umgebungsvariablen konfigurieren

cp .env.example .env
# .env mit API-Keys befüllen

5. Applikation starten

streamlit run frontend/app.py

6. Tests ausführen

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              │
└─────────────────────────────────────────────────────────────────┘