---
title: "Ein Plugin erstellen · Docs · SourceAnt"
description: "Dokumentation: Erweitern Sie den SourceAnt-Core mit Ihrer eigenen Erfassung, Anreicherung und Automatisierung oder tauschen Sie Ihren eigenen Speicher hinter den Wissen- und Topologie-Schnittstellen aus."
url: "https://sourceant.ai/de/docs/plugins/"
---

# Ein Plugin erstellen

Das Plugin-System von SourceAnt ermöglicht es Ihnen, die Plattform mit benutzerdefinierten Integrationen, Authentifizierungsanbietern, LLM-Backends und mehr zu erweitern.

## Übersicht

Plugins sind Python-Klassen, die von `BasePlugin`. erben. Jedes Plugin deklariert seinen Typ, Metadaten und Lifecycle-Hooks. Der Plugin-Manager übernimmt automatisch Discovery, Abhängigkeitsauflösung und Lifecycle-Verwaltung.

### Plugin-Typen

Jedes Plugin muss einen der folgenden Typen über das `PluginType` Enum deklarieren:

-   **INTEGRATION.** Integrationen externer Dienste (GitHub, GitLab usw.)
-   **AUTHENTICATION.** Authentifizierungsanbieter (OAuth, SAML usw.)
-   **LLM.** Sprachmodell-Backends
-   **WEBHOOK.** Webhook-Handler
-   **NOTIFICATION.** Benachrichtigungskanäle (Slack, E-Mail usw.)
-   **UTILITY.** Hilfsprogramme

## Schnellstart

Erstellen Sie ein neues Verzeichnis unter `src/plugins/` mit einer `plugin.py` Datei:

```
src/plugins/
  my_plugin/
    plugin.py
    __init__.py
```

Hier ist ein minimales Plugin:

```
from src.core.plugins import BasePlugin, PluginMetadata, PluginType


class MyPlugin(BasePlugin):

    @property
    def metadata(self) -> PluginMetadata:
        return PluginMetadata(
            name="my_plugin",
            version="1.0.0",
            description="A custom plugin",
            author="Your Name",
            plugin_type=PluginType.UTILITY,
        )

    async def _initialize(self) -> None:
        # One-time setup: register routes, connect to services
        pass

    async def _start(self) -> None:
        # Called after all plugins are initialized
        pass

    async def _stop(self) -> None:
        # Graceful shutdown
        pass

    async def _cleanup(self) -> None:
        # Final cleanup before unload
        pass
```

## Plugin-Metadaten

Der `PluginMetadata` dataclass definiert die Identität und Konfiguration Ihres Plugins:

| Feld | Typ | Beschreibung |
| --- | --- | --- |
| `name` | `str` | Eindeutiger Plugin-Bezeichner |
| `version` | `str` | Semantische Version (z. B. `"1.0.0"`) |
| `description` | `str` | Kurze Beschreibung |
| `author` | `str` | Plugin-Autor |
| `plugin_type` | `PluginType` | Einer der Enum-Werte des Plugin-Typs |
| `dependencies` | `List[str]` | Namen der Plugins, von denen dieses abhängt (Standard: `[]`) |
| `config_schema` | `Dict` | JSON Schema für die Konfigurationsvalidierung (Standard: `None`) |
| `enabled` | `bool` | Ob das Plugin aktiv ist (Standard: `True`) |
| `priority` | `int` | Ladepriorität, niedriger = früher (Standard: `100`) |

## Lifecycle-Hooks

Plugins folgen einem strikten Lifecycle, der von der `PluginManager`:

1.  **Discovery.** Der Manager durchsucht Plugin-Verzeichnisse nach `plugin.py` oder `__init__.py`
2.  **Loading.** Plugin-Klassen werden importiert und instanziiert
3.  **Registration.** Metadaten werden validiert und das Plugin wird registriert
4.  **Initialization.** `_initialize()` wird in Abhängigkeitsreihenfolge aufgerufen
5.  **Startup.** `_start()` wird aufgerufen, nachdem alle Plugins initialisiert wurden
6.  **Shutdown.** `_stop()` wird in umgekehrter Abhängigkeitsreihenfolge aufgerufen
7.  **Cleanup.** `_cleanup()` wird ausgeführt, bevor das Plugin entladen wird

Überschreiben `_initialize`, `_start`, `_stop`, und `_cleanup` in Ihrem Plugin. Die Methoden der Basisklasse (`initialize`, `start`, usw.) übernehmen die Zustandsverfolgung und rufen Ihre Implementierungen auf.

## Ereignissystem

Plugins interagieren mit SourceAnt über Hook-Punkte und Ereignis-Abonnements.

### Hook-Punkte

Registrieren Sie Callbacks für integrierte Lifecycle-Ereignisse:

```
from src.core.plugins import event_hooks, HookPriority

# In your _initialize method:
event_hooks.register_hook(
    hook_name="before_review_generation",
    callback=self._on_before_review,
    plugin_name=self.metadata.name,
    priority=HookPriority.NORMAL,
)
```

Verfügbare Hook-Punkte:

-   **App-Lifecycle.** `app_startup`, `app_shutdown`
-   **Webhooks.** `before_webhook_processing`, `after_webhook_processing`
-   **Code-Reviews.** `before_review_generation`, `after_review_generation`, `before_review_posting`, `after_review_posting`
-   **Authentifizierung.** `before_user_authentication`, `after_user_authentication`, `before_user_logout`, `after_user_logout`
-   **Repositories.** `before_repository_authorization`, `after_repository_authorization`, `before_webhook_setup`, `after_webhook_setup`
-   **Fehler.** `on_error`, `on_plugin_error`

### Ereignis-Abonnements

Abonnieren Sie domänenspezifische Ereignisse für eine granularere Steuerung:

```
event_hooks.subscribe_to_events(
    plugin_name=self.metadata.name,
    callback=self._handle_event,
    event_types=[
        "pull_request.opened",
        "pull_request.synchronize",
    ],
)
```

## Hook-Priorität

Steuern Sie die Ausführungsreihenfolge von Hooks mit `HookPriority`:

| Ebene | Wert | Anwendungsfall |
| --- | --- | --- |
| `HIGHEST` | 0 | Sicherheitsprüfungen, Validierung |
| `HIGH` | 25 | Vorverarbeitung, Anreicherung |
| `NORMAL` | 50 | Standardverarbeitung (Standard) |
| `LOW` | 75 | Nachverarbeitung, Protokollierung |
| `LOWEST` | 100 | Bereinigung, Analytik |

## Plugin-Discovery

Der `PluginManager` entdeckt Plugins automatisch durch Scannen registrierter Verzeichnisse. Damit ein Plugin entdeckt wird, muss es:

1.  sich in einem Unterverzeichnis eines registrierten Plugin-Verzeichnisses befinden
2.  entweder eine `plugin.py` oder `__init__.py` Datei
3.  Exportieren Sie eine Klasse, die erbt von `BasePlugin`

Verzeichnisse, die mit einem Unterstrich beginnen, werden übersprungen.

## Abhängigkeiten

Deklarieren Sie Abhängigkeiten in Ihren Metadaten, um eine korrekte Ladereihenfolge sicherzustellen:

```
PluginMetadata(
    name="my_plugin",
    version="1.0.0",
    description="Depends on GitHub OAuth",
    author="Your Name",
    plugin_type=PluginType.INTEGRATION,
    dependencies=["github_oauth"],
)
```

Die Plugin-Registry verwendet topologische Sortierung, um den Abhängigkeitsgraphen aufzulösen. Zirkuläre Abhängigkeiten werden erkannt und führen beim Laden zu einem Fehler. Die `_initialize` Methode eines Plugins wird erst aufgerufen, nachdem alle seine Abhängigkeiten initialisiert wurden.

## Konfigurationsvalidierung

Definieren Sie ein JSON Schema in `config_schema` um die Plugin-Konfiguration beim Laden zu validieren:

```
PluginMetadata(
    name="my_notifier",
    version="1.0.0",
    description="Slack notifications",
    author="Your Name",
    plugin_type=PluginType.NOTIFICATION,
    config_schema={
        "type": "object",
        "properties": {
            "webhook_url": {"type": "string"},
            "channel": {"type": "string"},
        },
        "required": ["webhook_url"],
    },
)
```

Greifen Sie in Ihrem Plugin mit auf validierte Konfigurationswerte zu `self.get_config("webhook_url")`.
