Imported from MrDerunov/telegram-exporter (
AGENTS.md). Install upstream withnpx skills add MrDerunov/telegram-exporter. Copyright stays with the author.
AGENTS.md — Правила для AI-агентов
1. Базовые правила
<common_rules>
- Отвечай на русском языке
- **КРИТИЧЕСКИ: Перед тем как вносить изменения, опиши общий план реализации по пунктам (CoT-планирование) и после приступай к реализации
- Не давай детальные пояснения, но описывай ЗАЧЕМ ты вносишь данные изменения (PURPOSE, а не DESCRIPTION)
- При генерации кода следуй принципам AI-friendly code: линейность, явность, локализация связанных блоков, без глубокой вложенности (max 3-4 уровня), информативные имена
- **КРИТИЧЕСКИ: Документы и описания, которые генерирует агент, должны быть достаточно полны, чтобы разобраться, и достаточно кратки, чтобы не утонуть. Не создавай «простыни текста» — раскрывай суть без лишних деталей
</common_rules>
<anti_semantic_collapse>
Правило: Режим суперпозиции смыслов (Anti-Semantic Collapse)
- Запрет на преждевременный коллапс: При получении сложной задачи (архитектура, сложный баг, выбор библиотеки) никогда не переходи к генерации кода немедленно.
- Анализ вариантов: Сначала вербализируй несколько альтернативных планов реализации в состоянии суперпозиции. Рассматривай их как одновременно существующие и валидные.
- Критериальная оценка: Для каждого варианта выведи семантические веса по следующим осям:
- Производительность: риск просадки (особенно для алгоритмов бекенда).
- Надежность: вероятность галлюцинаций из-за версионности фреймворков.
- Соответствие ТЗ: близость к изначальным целям (Belief State).
- Удержание инициативы: После анализа вариантов остановись и дождись моей команды на «семантический коллапс» (выбор конкретного пути).
- Защита от «бабушкиного IT»: Если одно из решений является стандартным паттерном, а другое — инновационным (know-how), не критикуй инновацию ради «баланса». Оценивай их через призму эффективности для текущей семантической капсулы
</anti_semantic_collapse>
Архитектурные принципы
- Component architecture — каждый файл содержит ровно один класс/компонент. Имя файла — snake_case от имени класса.
- Dependency Injection (DI) — зависимости собираются в
CliHost.build(), никаких глобальных синглтонов. Потребители зависят от абстракций, а не от конкретных реализаций. - Clean separation of concerns — чёткое разделение на слои: CLI → Core → Services → Models. Модели не знают о сервисах, сервисы не знают о CLI, модельный слой не зависит от Telethon.
- Иммутабельные модели —
ExportMessage,ExportTaskи подобные — frozen dataclasses. Изменение — черезdataclasses.replace().
Комментарии и документация
- НИКОГДА не удалять комментарии из кода и документации. Комментарии полезны при чтении кода. При рефакторинге сохраняй все пояснения, описания мотивации, примеры, docstring.
- Если комментарий больше не соответствует логике — обнови его, но не удаляй.
- Если метод/класс изначально имел docstring с объяснением мотивации — сохраняй его.
Стиль кода
- Код на русском не комментировать (комментарии в проекте на русском — это норма, не переводить на английский).
- Следовать существующему стилю в файле при внесении изменений.
Тестирование
- Все тесты пишутся на pytest.
unittest.TestCaseне используется. - Для проверки исключений —
pytest.raises(), для ассертов — нативныйassert.
Стратегия выбора типа теста
Перед написанием тестов определи тип теста по размеру и сложности компонента:
| Тип теста | Когда использовать | Папка | Базовый класс |
|---|---|---|---|
| Unit | Простые, чистые компоненты без внешних зависимостей или с 1-2 простыми зависимостями | unit/ |
— (без наследования) |
| Func | Компоненты с несколькими зависимостями, бизнес-логикой, взаимодействием с другими сервисами | func/ |
Базовый класс тестов (*_tests_base) |
| Integration | Связка нескольких подсистем, требующих реального взаимодействия | integration/ |
Базовый класс тестов (*_tests_base) |
- Простой компонент (чистая логика, 0-2 зависимости) → Unit-тест. Для зависимостей можно использовать конкретные реализации, fake-реализации, либо mock, если тест остаётся коротким. Без DI.
- Средний/большой компонент (3+ зависимости, бизнес-процессы) → Func-тест с DI и фейковыми реализациями.
- Компонент, зависящий от ещё не реализованной подсистемы → Integration-тест, либо создать TODO-запись и отложить.
- Если сомневаешься — лучше Func-тест с фейками, чем Unit-тест с моками.
Что тестировать (публичный контракт)
Тесты проверяют только публичный контракт компонента:
- Возвращаемые значения методов
- Состояние публичных свойств после операций
- Генерируемые события
- Выбрасываемые исключения
ЗАПРЕЩЕНО проверять внутреннюю реализацию.
Структура файлов
tests/
├── unit/
├── func/
├── integration/
└── common/
└── fakes/
- Имя файла тестов:
test_{class_name}.py(стандартная конвенция Python/pytest) - Имя файла fake-реализации:
fake_{interface_name}.py(вcommon/fakes/) - Имя базового класса тестов:
test_{class_name}_base.py(в папкеfunc/илиintegration/)
Описания тестов
Для Func-тестов и Integration-тестов обязательно добавлять docstring на русском языке, поясняющий что проверяет тест:
def test_return_initial_delay_on_first_attempt(self):
"""Возвращает начальную задержку при первой попытке."""
...
Конвенция наименования тестов
Паттерн: test_{expected_behavior}[_when_{condition}][_then_{condition}]
Примеры хороших названий:
test_return_initial_delay_on_first_attempt
test_grow_delay_exponentially_with_default_multiplier
test_clamp_delay_when_exceeds_max
test_throw_when_multiplier_is_not_positive
test_not_throw_on_reset
test_execute_successful_operation_once
test_handle_exceptions_as_failure
test_respect_cancellation_token
test_return_correct_IsExecuting_status
Плохие названия (избегать):
GetDelay_FirstAttempt_ReturnsInitialDelay # MethodName_Condition_Result
TestGetDelay # префикс "Test"
ExponentialBackoff_Works # слишком размыто
Категории для покрытия
Генерировать тесты для следующих категорий (когда применимо):
- Happy path — базовое корректное поведение
- Edge cases — граничные значения, ноль, пустота, отрицательные
- Validation — невалидные аргументы выбрасывают ожидаемые исключения
- Overflow/limits — большие значения, защита от переполнения
- State management — сброс, поведение без состояния
- Events/notifications — событие вызывается при изменении, НЕ вызывается при отсутствии изменений
- Thread safety — для компонентов с lock: чтение из обработчика события не вызывает deadlock (Changed вне lock)