Руководство по плагинам
Обзор архитектуры
Проект использует модульную архитектуру на основе плагинов. Все плагины находятся в папке plugins/ и делятся на два основных типа:
📋 Подробная архитектура проекта: Архитектура проекта
📁 Структура папок
plugins/
├── utilities/ # Вспомогательные утилиты
│ ├── foundation/ # Фундаментальные утилиты (logger, plugins_manager)
│ ├── custom_layers/ # Тематические слои (telegram, api, database)
│ ├── core/ # Core утилиты (event_processor, database_service)
│ └── extensions/ # Расширения утилит (не входят в базовую версию платформы)
└── services/ # Бизнес-сервисы
├── core/ # Core сервисы
├── hub/ # Hub сервисы
├── additional/ # Дополнительные сервисы
└── extensions/ # Расширения сервисов (не входят в базовую версию платформы)Типы плагинов
🔧 Утилиты (Utilities)
- Назначение: Вспомогательные компоненты для расширения функционала
- Особенности:
- Не могут работать автономно
- Передаются в сервисы как зависимости через DI
- Могут иметь зависимости от других утилит
- Организуются по специальным слоям и уровням
📋 Концептуальное описание слоев: Архитектура проекта - Слои и их назначение
🚀 Сервисы (Services)
- Назначение: Основная бизнес-логика приложения
- Особенности:
- Работают автономно и асинхронно
- Могут иметь опциональный метод
run()для фонового запуска - Могут зависеть от утилит (foundation, level-слои, core, database)
- Могут быть организованы в подкатегории (core, hub, additional)
🔌 Расширения (Extensions)
- Назначение: Дополнительные плагины для расширения функционала платформы
- Особенности:
- Могут быть как утилитами, так и сервисами
- Размещаются в
plugins/utilities/extensions/илиplugins/services/extensions/ - Позволяют добавлять новый функционал без изменения базовой платформы
- Не затираются при обновлении платформы
- Добавляются пользователями по необходимости
- Работают по тем же правилам, что и обычные плагины
Практические примеры использования слоев
Foundation — Когда использовать?
Используйте для:
- Логирования (logger)
- Управления плагинами (plugins_manager)
- Любых утилит, которые нужны для запуска DI-контейнера
Примеры:
# ✅ Правильно: logger использует только системные библиотеки
import logging
import sys
from datetime import datetime
class Logger:
def __init__(self):
# Только системные библиотеки Python
passCustom Layers — Когда использовать?
Используйте для:
- Тематических утилит (telegram, api, etc.)
- Утилит для конкретных технологий или платформ
- Группировки связанных утилит по функциональности
- Утилит внутри своего слоя (не рекомендуется использование из других custom-слоев)
Core — Когда использовать?
Используйте для:
- Обработки событий (event_processor)
- Работы с базой данных (database_service)
- Любых инфраструктурных утилит высокого уровня
Services — Когда использовать?
Используйте для:
- Бизнес-логики приложения
- Обработки действий из очереди
- Автономных сервисов с методом
run()
Extensions — Когда использовать?
Используйте для:
- Расширения функционала платформы дополнительными плагинами
- Добавления нового функционала без изменения базовой платформы
- Плагинов, которые не должны затираться при обновлении платформы
- Создания собственных плагинов для специфических задач
Как добавить расширение:
- Скопировать папку плагина в
plugins/utilities/extensions/илиplugins/services/extensions/ - Убедиться, что в папке есть
config.yaml - Перезапустить приложение
Расширения автоматически обнаруживаются и загружаются системой без дополнительной настройки.
Правила создания плагинов
1. Структура папки плагина
my_plugin/
├── config.yaml # ОБЯЗАТЕЛЬНО! Без него плагин не будет обнаружен
├── my_plugin.py # Основной код плагина
└── README.md # Документация (опционально)⚠️ Важно: Файл config.yaml является обязательным для всех плагинов. Без него плагин не будет обнаружен системой и не сможет работать.
2. Определение типа плагина
Тип плагина определяется автоматически по расположению:
- Если плагин находится в
plugins/utilities/→ утилита - Если плагин находится в
plugins/services/→ сервис
3. Поддержка вложенности
Плагины могут находиться на любой глубине вложенности:
plugins/
├── utilities/
│ ├── foundation/
│ │ ├── logger/ # Foundation утилита
│ │ └── plugins_manager/ # Foundation утилита
│ ├── telegram/
│ │ ├── telegram_api/ # Telegram Bot API
│ │ └── telegram_polling/ # Telegram polling
│ ├── core/
│ │ ├── action_hub/ # Core утилита
│ │ └── database_manager/ # Core утилита
│ └── extensions/
│ └── http_server/ # Extension утилита
└── services/
├── core/
│ ├── event_processor/ # Core сервис
│ └── scenario_processor/ # Core сервис
├── hub/
│ ├── bot_hub/ # Hub сервис
│ └── tenant_hub/ # Hub сервис
├── additional/
│ └── ai_service/ # Additional сервис
└── extensions/
├── http_api_service/ # Extension сервис
└── ai_rag_service/ # Extension сервис (RAG функционал)Конфигурация плагина (config.yaml)
Подробное описание структуры конфигурационных файлов для всех типов плагинов (утилит и сервисов) находится в отдельном документе:
📋 Шаблоны YAML-конфигов для сервисов и утилит
Этот документ содержит:
- Универсальный шаблон для всех утилит (Foundation, Core, Database, Level N)
- Шаблон для сервисов
- Обязательные и опциональные секции
- Примеры конфигураций
- Правила зависимостей
- Ключевые различия между утилитами и сервисами
Система зависимостей
📋 Иерархия зависимостей и правила: Архитектура проекта - Иерархия зависимостей
Пример зависимостей
# Foundation утилита (logger)
# dependencies: отсутствует (использует только системные библиотеки)
# Custom layer утилита (tg_bot_api)
dependencies:
- "logger" # Foundation утилита
- "settings_manager" # Foundation утилита
# Сервис (chat_service)
dependencies:
- "logger" # Foundation утилита
- "database_service" # Core утилита
- "event_processor" # Core утилита
# Плагин с опциональными зависимостями (любой тип)
dependencies:
- "logger" # Обязательная зависимость
- "hash_manager" # Обязательная зависимость
optional_dependencies:
- "cache_service" # Опциональная зависимость
- "analytics_service" # Опциональная зависимостьПримечание: Опциональные зависимости не влияют на порядок инициализации и не вызывают ошибок при отсутствии.
Инициализация и порядок загрузки
Алгоритм инициализации
- Сканирование всех плагинов рекурсивно
- Построение графа зависимостей
- Проверка циклических зависимостей
- Топологическая сортировка утилит
- Инициализация утилит в порядке зависимостей
- Инициализация сервисов (в любом порядке)
Пример порядка инициализации
1. logger (foundation, нет зависимостей)
2. plugins_manager (foundation, зависит от logger)
3. settings_manager (foundation, зависит от logger)
4. tg_bot_api (telegram layer, зависит от logger, settings_manager)
5. tg_permission_manager (telegram layer, зависит от logger, tg_bot_api)
6. event_processor (core, зависит от logger, settings_manager, database_service)
7. chat_service (зависит от logger, database_service, event_processor)Лучшие практики
✅ Рекомендуется
- Использовать осмысленные имена плагинов
- Группировать связанные утилиты по соответствующим слоям
- Документировать зависимости и интерфейсы
- Следовать принципу единственной ответственности
- Использовать типизацию в конфигурации
- Foundation утилиты должны использовать только системные библиотеки Python
❌ Запрещено
- Создавать циклические зависимости - система не поддерживает и приложение не запустится
- Создавать плагины без config.yaml - плагин не будет обнаружен и не заработает
- Делать сервисы зависимыми от сервисов - нарушает архитектуру
- Foundation утилиты не должны зависеть от других утилит
⚠️ Не рекомендуется
- Использовать слишком глубокую вложенность (>5 уровней)
- Дублировать функционал в разных плагинах
- Custom layer утилиты использовать утилиты из других custom-слоев без необходимости
Отладка и диагностика
Проверка зависимостей
# КРИТИЧНО: Проверить циклические зависимости
if not plugins_manager.check_circular_dependencies():
print("❌ ОБНАРУЖЕНЫ ЦИКЛИЧЕСКИЕ ЗАВИСИМОСТИ!")
print("Приложение не запустится. Исправьте зависимости.")
# Получить порядок инициализации
order = plugins_manager.get_dependency_order()
print("Порядок инициализации:", order)
# Получить зависимости конкретного плагина
deps = plugins_manager.get_plugin_dependencies("my_plugin")
print("Зависимости:", deps)
# Проверить наличие config.yaml у всех плагинов
missing_configs = plugins_manager.find_plugins_without_config()
if missing_configs:
print("❌ ПЛАГИНЫ БЕЗ config.yaml:", missing_configs)
print("Эти плагины не будут обнаружены системой!")
# Проверить Foundation утилиты на использование только системных библиотек
foundation_issues = plugins_manager.check_foundation_utilities()
if foundation_issues:
print("❌ FOUNDATION УТИЛИТЫ ИСПОЛЬЗУЮТ ДРУГИЕ УТИЛИТЫ:", foundation_issues)Логирование
Все операции с плагинами логируются:
- Загрузка конфигураций
- Обнаружение плагинов
- Ошибки зависимостей
- Порядок инициализации
- Проверка Foundation утилит
Миграция и обновления
Добавление нового плагина
- Создать папку в соответствующей директории (foundation/core/database/level_N/services)
- Добавить
config.yamlс описанием - Реализовать код плагина
- Перезапустить приложение
Изменение зависимостей
- Обновить
config.yaml - Проверить отсутствие циклических зависимостей
- Убедиться в соблюдении иерархии зависимостей
- Перезапустить приложение
Удаление плагина
- Удалить папку плагина
- Убрать зависимости из других плагинов
- Перезапустить приложение