# 🧩 Komponenten-Standardstruktur ## 1. Ziel Dieses Dokument beschreibt die einheitliche interne Struktur, den Lebenszyklus und die Schnittstellen aller Programme, Module und Komponenten im KI-Cluster. Ziel ist, dass jede Komponente – ob Router, API-Server, Agent, Speicher oder Tool – nach demselben Aufbau funktioniert und sich konsistent starten, erweitern und warten lässt. --- ## 2. Grundprinzip Jede Komponente ist ein eigenständiges, klar abgegrenztes Modul. Eine Komponente kann: - Aufgaben empfangen (z. B. vom Router oder über eine API), - eigene Logik ausführen (lokal oder verteilt), - Ergebnisse speichern oder weiterleiten, - und Statusinformationen melden. Diese Struktur erlaubt, dass alle Module untereinander austauschbar bleiben und dennoch einheitlich funktionieren. --- ## 3. Standardverzeichnisstruktur ```plaintext // │ ├── Planung/ │ ├── Architektur.md │ ├── Funktionsbeschreibung.md │ └── Kommunikationsschnittstellen.md │ ├── Entworfener_Code/ │ ├── start.py │ ├── config.yaml │ ├── src/ │ │ ├── core.py │ │ ├── logic.py │ │ ├── api_connector.py │ │ └── storage.py │ ├── tests/ │ │ └── test_core.py │ └── README.md │ └── README.md ``` --- ## 4. Klassenaufbau Jede Komponente kann, falls objektorientiert entwickelt, auf einer einheitlichen Basisklasse aufbauen, um Grundfunktionen wie Logging, Config-Handling und Kommunikation gemeinsam zu nutzen. ```python # Datei: src/core.py from utils.api_client import APIClient from utils.memory_connector import Memory from utils.logging_setup import get_logger class BaseComponent: """Abstrakte Basisklasse für alle Komponenten des KI-Clusters.""" def __init__(self, name: str): self.name = name self.api = APIClient() self.memory = Memory() self.logger = get_logger(name) def register(self): """Registriert die Komponente beim Router oder Systembus.""" self.logger.info(f"{self.name} registriert sich beim System.") self.api.register_component(self.name) def start(self): raise NotImplementedError("Jede Komponente muss eine start()-Methode implementieren.") ``` Beispiel für eine spezialisierte Komponente: ```python # Beispiel: Router-Modul from src.core import BaseComponent class RouterModule(BaseComponent): """Koordiniert Aufgaben zwischen Komponenten und verteilt Anfragen.""" def start(self): self.logger.info("Router gestartet.") self.listen_for_tasks() def listen_for_tasks(self): # Beispielhafte Implementierung self.logger.info("Warte auf eingehende Aufgaben...") ``` --- ## 5. Lebenszyklus einer Komponente | Phase | Beschreibung | |--------|---------------| | **Initialisierung** | `start.py` lädt Konfiguration, Logging und die `src/core.py`-Klasse. | | **Registrierung** | Komponente meldet sich beim Router oder globalen System an. | | **Ausführung** | Logik läuft (z. B. Verarbeitung, API-Handling, Kommunikation). | | **Feedback** | Ergebnisse oder Status werden an zentrale Systeme übermittelt. | | **Beendigung** | Logs und Speicherzustände werden gesichert, Prozesse sauber beendet. | --- ## 6. Konfigurationsdatei (`config.yaml`) Beispiel: ```yaml component: name: "RouterModule" type: "Systemkomponente" version: "1.0" communication: router_endpoint: "http://localhost:5000" memory_endpoint: "http://localhost:6000" logging: level: "INFO" file: "logs/router_module.log" ``` --- ## 7. Gemeinsame Schnittstellen | Schnittstelle | Zweck | Implementierung | |----------------|--------|------------------| | **APIClient** | Kommunikation zwischen Komponenten | `utils/api_client.py` | | **Memory** | Zugriff auf Wissensspeicher | `utils/memory_connector.py` | | **Logger** | Zentrales Logging-System | `utils/logging_setup.py` | | **Config Loader** | Einheitliche YAML-Konfiguration | `utils/config_loader.py` | --- ## 8. Kommunikation zwischen Komponenten Jede Komponente unterstützt mindestens folgende Methoden: | Methode | Beschreibung | |----------|---------------| | `register()` | Meldet sich beim zentralen System an | | `start()` | Startet die Logik der Komponente | | `receive_message(data: dict)` | Empfängt Nachrichten oder Aufgaben | | `send_message(data: dict)` | Sendet Ergebnisse oder Events | | `shutdown()` | Fährt die Komponente kontrolliert herunter | --- ## 9. Anforderungen an neue Komponenten Neue Komponenten müssen: 1. von `BaseComponent` erben (falls OOP), 2. in `start.py` eingetragen werden, 3. ihre Konfiguration in `config.yaml` speichern, 4. Unit-Tests unter `/tests/` bereitstellen, 5. und saubere Logging- sowie Feedback-Mechanismen besitzen. --- ## 10. Beispielkommunikation ```python # Beispiel: Router sendet Aufgabe an API-Modul task = { "type": "fetch_data", "parameters": {"url": "https://example.com/api"} } api_module.receive_message(task) ``` Die Komponente führt die Aufgabe aus und antwortet: ```python result = { "status": "success", "data": {"records": 24} } api_module.send_message(result) ``` --- ## 11. Zusammenfassung Alle Komponenten im System folgen diesem Grundschema. Dadurch wird erreicht, dass: - der Router alle Programme gleich ansprechen kann, - der Builder-Agent neue Komponenten automatisch integrieren kann, - und das gesamte System modular, testbar und erweiterbar bleibt. --- © 2025 – KI-Cluster Homelab Architektur Autor: *[Dein Name oder Alias]* ### 3.1 Variante: FastAPI-Web-API-Komponente (empfohlen) Diese Variante verankert die lauffähige Grundstruktur für API-basierte Komponenten mit FastAPI, Logging und Tests. ```plaintext // │ ├── Planung/ │ ├── Architektur.md │ ├── Funktionsbeschreibung.md │ └── Kommunikationsschnittstellen.md │ ├── Entworfener_Code/ │ ├── start.py │ ├── requirements.txt │ ├── README.md │ ├── Dockerfile │ ├── docker-compose.yml │ ├── app/ │ │ └── main.py │ ├── api/ │ │ ├── __init__.py │ │ ├── router.py │ │ └── routes/ │ │ ├── __init__.py │ │ └── execute.py │ ├── core/ │ │ └── base_component.py │ ├── config/ │ │ ├── config.yaml │ │ └── logging.yaml │ └── tests/ │ └── test_smoke.py │ └── README.md ``` Pflichten dieser Struktur: - start.py: lädt Konfiguration (config/config.yaml), initialisiert Logging (config/logging.yaml) und startet den FastAPI-Server (uvicorn, optional Factory/Reload). - app/main.py: erzeugt die FastAPI-App (create_app), bindet CORS und registriert Router. - api/router.py und api/routes/execute.py: Beispiel-Routenstruktur inkl. POST /api/execute sowie GET /health. - core/base_component.py: Basisklasse mit Schnittstelle register() und start() für spätere Komponenten. - config/logging.yaml: Rotierende Logs (TimedRotatingFileHandler) und zentrale Logger (uvicorn, root). - tests/test_smoke.py: pytest-Smoketests für Health-Endpoint und /api/execute. - requirements.txt: Abhängigkeiten (u. a. fastapi, uvicorn, pyyaml, pytest, httpx). - Dockerfile, docker-compose.yml: Containerisierter Betrieb, Port 8000, Mounts für config/logs. - Namens-/Code-Style: snake_case, vollständige Typannotationen, Docstrings gemäß Richtlinien. Hinweis: Diese Variante ergänzt die allgemeine Standardstruktur aus Abschnitt 3 für API-orientierte Komponenten und dient als verbindlicher Grundstock, auf dem spätere Erweiterungen aufbauen. ## 12. Laufzeit-Zielsetzung und Start-Events - Das Laufzeitprogramm `start.py` bleibt dauerhaft aktiv, da es einen Webserver offen hält und Anfragen entgegennimmt. - Der Code ist so vorzubereiten, dass bei eingehenden Start-Events (z. B. POST /start) ein Start-Prozess ausgelöst werden kann. - Mehrere Start-Events dürfen möglich sein. Die Entscheidung, ob diese ignoriert, parallel oder in einer Queue verarbeitet werden, wird in dieser Phase bewusst offengelassen und nur als Planungs-Hinweis dokumentiert. Die konkrete Ausführungsstrategie wird später festgelegt. --- ## 13. API-Struktur (Minimal-API unter src/api.py) - Eine Minimal-API wird in `src/api.py` bereitgestellt. - Der Webserver lauscht auf dem in der Konfiguration definierten Port (Standard 8000). - `start.py` startet den API-Server und bleibt aktiv, um Anfragen verarbeiten zu können. - Die Minimal-API umfasst mindestens: - POST /start: löst den Start-Prozess aus (nicht-blockierend). - Optional GET /health: einfacher Health-Check. - Die API darf den Event-Handling-Pfad nicht blockieren; Start-Prozesse werden asynchron oder in eigenen Threads/Tasks ausgeführt. --- ## 14. Globales Konfigurationssystem Es gibt eine einzige globale Konfiguration. Die Struktur ist folgendermaßen vorgegeben: ```plaintext +-- globale_configuration | |-- variablename | | |-- beschreibung erklärung | | |-- wert | +-- logging | |-- variablename | | |-- beschreibung erklärung | | |-- wert | +-- worker |-- variablename | |-- beschreibung erklärung | |-- wert ``` - Diese Konfiguration wird als Python-Struktur in `src/config.py` gepflegt und systemweit verwendet. - Zugriff erfolgt zentral über `from src.config import CONFIG`. - Der HTTP-Port wird ebenfalls in der globalen Konfiguration gepflegt (z. B. `CONFIG["globale_configuration"]["port"]["wert"]`). - Logging-Parameter (Level, Aktivierung, Ausgabeziele) werden ausschließlich über `CONFIG` gesteuert. --- ## 15. Technische Anforderungen (Laufzeit und Architektur) - Der Webserver darf beim Event-Handling nicht blockieren. HTTP-Handler delegieren die Start-Logik in asynchrone Tasks oder Threads. - Start-Routinen laufen asynchron (z. B. asyncio/BackgroundTasks) oder in eigenen Threads, sodass die API schnell antwortet. - Logging ist vollständig über die globale Konfiguration steuerbar (z. B. Level, Aktivierung). - Modulstruktur: - start.py: Einstiegspunkt (startet Webserver, bleibt aktiv) - src/config.py: zentrale Konfiguration (`CONFIG`) - src/api.py: API-Definition (u. a. POST /start) - src/worker.py: Start-/Arbeitslogik (ausgelöst durch Events) - src/logger.py: Logging-Setup/-Zugriff --- ## 16. Beispiel-/Gerüstcode in Entworfener_Code Hinweis: Es handelt sich um Struktur- und Ablaufgerüste (kein finaler Code, keine vollständige Implementierung). Ziel ist, Verantwortlichkeiten und Aufrufreihenfolge klar zu dokumentieren. Beispiel src/config.py: ```python # Globale Konfiguration als Python-Struktur (zentrale Quelle der Wahrheit) CONFIG: dict = { "globale_configuration": { "port": { "beschreibung": "HTTP-Port des API-Servers", "wert": 8000, }, "environment": { "beschreibung": "Laufzeitumgebung", "wert": "dev", }, }, "logging": { "enabled": {"beschreibung": "Aktiviert das Logging", "wert": True}, "level": {"beschreibung": "Log-Level (z. B. INFO, DEBUG)", "wert": "INFO"}, }, "worker": { "concurrency": { "beschreibung": "Parallelisierungsgrad (Threads/Tasks), strategische Nutzung offen", "wert": 1, }, }, } ``` Beispiel src/logger.py: ```python import logging from src.config import CONFIG def get_logger(name: str) -> logging.Logger: logger = logging.getLogger(name) logger.setLevel(getattr(logging, str(CONFIG["logging"]["level"]["wert"]).upper(), logging.INFO)) return logger ``` Beispiel src/worker.py: ```python from typing import Any, Dict from src.logger import get_logger async def trigger_start(payload: Dict[str, Any]) -> None: logger = get_logger("worker") logger.info("Start-Event angenommen (Gerüst).") ``` Beispiel src/api.py: ```python from typing import Any, Dict, Optional from fastapi import FastAPI, BackgroundTasks from pydantic import BaseModel from src.config import CONFIG from src.logger import get_logger from src.worker import trigger_start app = FastAPI(title="Minimal-API (Gerüst)") class StartRequest(BaseModel): job_id: Optional[str] = None params: Optional[Dict[str, Any]] = None @app.post("/start") async def start_endpoint(req: StartRequest, background: BackgroundTasks) -> Dict[str, str]: logger = get_logger("api") logger.info("Start-Event empfangen (Gerüst).") background.add_task(trigger_start, (req.dict())) return {"status": "accepted"} ``` Ablauf-Skizze start.py (Beschreibung): - Liest die globale Konfiguration aus `src/config.py` (oder eine projektspezifische Quelle). - Initialisiert das Logging über `src/logger.py`. - Startet den Webserver (z. B. `uvicorn src.api:app`) auf dem in `CONFIG` definierten Port und bleibt aktiv. - Nicht-blockierender Betrieb: API antwortet unmittelbar; Arbeitslogik läuft asynchron/parallel. ## 17. Restart-/Reload-Funktion (über API) Ziel - Während der Laufzeit soll eine über die API verfügbare Funktion einen Neustart des Python-Prozesses anstoßen, um Konfigurationsänderungen zu übernehmen oder nach Laufzeiterweiterungen sauber durchzustarten. - Endpunkte: `POST /restart` sowie Alias `POST /reload`. Vorgaben - Nicht-blockierend: Der HTTP-Handler bestätigt den Auftrag zeitnah und plant den Neustart im Hintergrund mit kurzer Verzögerung (z. B. 300–1000 ms), damit die Antwort noch übertragen werden kann. - Prozess-Neustart: Entweder durch einen Vollneustart des Python-Prozesses (z. B. via os.execv) oder durch einen Supervisor (Docker/Compose/Systemd/K8s). In der Scaffold-Phase wird der direkte Prozess-Neustart skizziert. - Konfiguration: Optionaler Request-Parameter `delay_ms` zur Steuerung der Verzögerung vor dem Neustart. Weitere Steuerung (z. B. Freigabe-Flag, Backoff) kann über die zentrale `CONFIG` erfolgen. - Sicherheit/Robustheit (Hinweise): - Schutz vor Restart-Loops (Backoff/Minimum-Delay). - Optional Authentisierung/Autorisierung für administrative Endpunkte. - Log-Einträge vor Neustart (Grund, Zeitstempel, Kontext). - Start-/Mehrfach-Events: Die Strategie für konkurrierende Ereignisse bleibt offen (ignorieren, parallel, Queue). Der Restart-Event ist administrativ und sollte priorisiert behandelt werden, Details werden in der späteren Implementierung festgelegt. Schnittstellenbeschreibung (Minimal) - `POST /restart` → Antwort: `{"status": "scheduled", "delay_ms": }` - `POST /reload` → Alias zu `/restart` Modulzuordnung - `src/api.py`: definiert die Endpunkte und plant den Neustart im Hintergrund. - `src/worker.py`: enthält die Restart-Hilfsroutine (z. B. `restart_process(reason, delay_seconds)`), die nach einer kurzen Verzögerung den Prozess ersetzt/neustartet. - `start.py`: bleibt dauerhaft aktiv; Neustart führt zur Neuinitialisierung inkl. erneuter Auswertung der Konfiguration. ## 3.2 Alternative Struktur: app/code-Aufteilung (empfohlen für klare Trennung) Diese Variante verschiebt den ausführbaren Code, Tests und die API-Struktur unterhalb von `app/code`, während Konfigurationsdateien unter `app/config` leben. Einstiegspunkt und komponentenbezogene README liegen unter `app/`. Artefakte wie Dockerfile, docker-compose und requirements verbleiben auf oberster Ebene von `Entworfener_Code/`. ```plaintext Entworfener_Code ├── app │ ├── code │ │ ├── api │ │ │ ├── __init__.py │ │ │ ├── router.py │ │ │ └── routes │ │ │ ├── execute.py │ │ │ └── __init__.py │ │ ├── app │ │ │ └── main.py │ │ ├── core │ │ │ └── base_component.py │ │ ├── src │ │ │ ├── api.py │ │ │ ├── config.py │ │ │ ├── logger.py │ │ │ └── worker.py │ │ └── tests │ │ └── test_smoke.py │ ├── config │ │ ├── config.yaml │ │ └── logging.yaml │ ├── README.md │ └── start.py ├── docker-compose.yml ├── Dockerfile └── requirements.txt ``` Leitlinien für diese Struktur: - `app/start.py` bleibt dauerhaft aktiv (Webserver offen) und liest Konfiguration aus `app/config`. - API für Start-Events und Admin-Endpunkte (POST `/start`, `/restart`, `/reload`) liegt in `app/code/src/api.py`. Diese Endpunkte dürfen nicht blockieren; Ausführung wird an `app/code/src/worker.py` delegiert (async/Threads). - Zentrale, einzige globale Konfiguration als Python-Struktur in `app/code/src/config.py` (`from src.config import CONFIG`); YAML-Konfigurationsdateien ergänzen diese bei Bedarf (z. B. für externe Operatoren) und werden in `app/config` gepflegt. - Logging wird über `CONFIG` gesteuert. Ein Gerüst für Logging-Zugriff liegt in `app/code/src/logger.py`; systemweite Handler/Formatter werden später konsolidiert. - Die beispielhafte Router-Struktur für REST-Endpunkte liegt in `app/code/api` und wird in `app/code/app/main.py` eingebunden. - Tests unter `app/code/tests` (pytest-Namenskonventionen `test_*.py`). Hinweis zu Restart/Reload: - Die Endpunkte `POST /restart` und `POST /reload` planen (nicht-blockierend) einen Prozessneustart ein, um Konfigurationsänderungen oder Erweiterungen aufzunehmen. Die konkrete Neustartstrategie (Supervisor/execv, Backoff, Auth) ist bewusst noch offen und wird in einer späteren Implementierungsphase festgelegt.