---
title: "Crear un plugin · Documentación · SourceAnt"
description: "Documentación: Amplíe el núcleo de SourceAnt con su propia captura, enriquecimiento y automatización, o sustituya su propio almacenamiento detrás de las interfaces de conocimiento y topología."
url: "https://sourceant.ai/es/docs/plugins/"
---

# Crear un plugin

El sistema de plugins de SourceAnt le permite ampliar la plataforma con integraciones personalizadas, proveedores de autenticación, backends LLM y más.

## Resumen

Los plugins son clases de Python que heredan de `BasePlugin`. Cada plugin declara su tipo, metadatos y hooks de ciclo de vida. El gestor de plugins maneja automáticamente el descubrimiento, la resolución de dependencias y la gestión del ciclo de vida.

### Tipos de plugins

Cada plugin debe declarar uno de los siguientes tipos mediante el `PluginType` enum:

-   **INTEGRATION.** Integraciones de servicios externos (GitHub, GitLab, etc.)
-   **AUTHENTICATION.** Proveedores de autenticación (OAuth, SAML, etc.)
-   **LLM.** Backends de modelos de lenguaje
-   **WEBHOOK.** Manejadores de webhooks
-   **NOTIFICATION.** Canales de notificación (Slack, Email, etc.)
-   **UTILITY.** Utilidades auxiliares

## Inicio rápido

Cree un nuevo directorio bajo `src/plugins/` con un `plugin.py` archivo:

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

Aquí hay un plugin mínimo:

```
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
```

## Metadatos del plugin

La `PluginMetadata` La dataclass define la identidad y configuración de su plugin:

| Campo | Tipo | Descripción |
| --- | --- | --- |
| `name` | `str` | Identificador único del plugin |
| `version` | `str` | Versión semántica (por ejemplo, `"1.0.0"`) |
| `description` | `str` | Descripción breve |
| `author` | `str` | Autor del plugin |
| `plugin_type` | `PluginType` | Uno de los valores del enum de tipo de plugin |
| `dependencies` | `List[str]` | Nombres de los plugins de los que depende (predeterminado: `[]`) |
| `config_schema` | `Dict` | Esquema JSON para la validación de la configuración (predeterminado: `None`) |
| `enabled` | `bool` | Si el plugin está activo (predeterminado: `True`) |
| `priority` | `int` | Prioridad de carga, menor = antes (predeterminado: `100`) |

## Hooks del ciclo de vida

Los plugins siguen un ciclo de vida estricto gestionado por el `PluginManager`:

1.  **Descubrimiento.** El gestor escanea los directorios de plugins en busca de `plugin.py` o `__init__.py`
2.  **Carga.** Las clases de plugin se importan y se instancian
3.  **Registro.** Los metadatos se validan y el plugin se registra
4.  **Inicialización.** `_initialize()` se llama en orden de dependencias
5.  **Arranque.** `_start()` se llama después de que todos los plugins se hayan inicializado
6.  **Apagado.** `_stop()` se llama en orden inverso de dependencias
7.  **Limpieza.** `_cleanup()` se ejecuta antes de que el plugin se descargue

Sobrescribir `_initialize`, `_start`, `_stop`, y `_cleanup` en su plugin. Los métodos de la clase base (`initialize`, `start`, etc.) gestionan el seguimiento del estado y llaman a sus implementaciones.

## Sistema de eventos

Los plugins interactúan con SourceAnt mediante puntos de enganche y suscripciones a eventos.

### Puntos de enganche

Registre callbacks para eventos integrados del ciclo de vida:

```
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,
)
```

Puntos de enganche disponibles:

-   **Ciclo de vida de la aplicación.** `app_startup`, `app_shutdown`
-   **Webhooks.** `before_webhook_processing`, `after_webhook_processing`
-   **Revisiones de código.** `before_review_generation`, `after_review_generation`, `before_review_posting`, `after_review_posting`
-   **Autenticación.** `before_user_authentication`, `after_user_authentication`, `before_user_logout`, `after_user_logout`
-   **Repositorios.** `before_repository_authorization`, `after_repository_authorization`, `before_webhook_setup`, `after_webhook_setup`
-   **Errores.** `on_error`, `on_plugin_error`

### Suscripciones a eventos

Suscríbase a eventos específicos de dominio para un control más granular:

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

## Prioridad de hooks

Controle el orden en que se ejecutan los hooks con `HookPriority`:

| Nivel | Valor | Caso de uso |
| --- | --- | --- |
| `HIGHEST` | 0 | Comprobaciones de seguridad, validación |
| `HIGH` | 25 | Preprocesamiento, enriquecimiento |
| `NORMAL` | 50 | Procesamiento estándar (predeterminado) |
| `LOW` | 75 | Posprocesamiento, registro |
| `LOWEST` | 100 | Limpieza, analítica |

## Descubrimiento de plugins

La `PluginManager` descubre automáticamente los plugins escaneando los directorios registrados. Para que un plugin sea descubierto, debe:

1.  Estar en un subdirectorio de un directorio de plugins registrado
2.  Contener un archivo `plugin.py` o `__init__.py` archivo
3.  Exportar una clase que herede de `BasePlugin`

Se omiten los directorios que empiezan por guion bajo.

## Dependencias

Declare las dependencias en sus metadatos para garantizar el orden de carga correcto:

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

El registro de plugins utiliza la ordenación topológica para resolver el grafo de dependencias. Las dependencias circulares se detectan y provocarán un error en el momento de la carga. El método `_initialize` de un plugin solo se llama después de que se hayan inicializado todas sus dependencias.

## Validación de la configuración

Definir un JSON Schema en `config_schema` para validar la configuración del plugin en el momento de la carga:

```
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"],
    },
)
```

Acceder a los valores de configuración validados en su plugin con `self.get_config("webhook_url")`.
