69 lines
5.2 KiB
Markdown
69 lines
5.2 KiB
Markdown
# Proposal: Классификация писем и подключение обработчиков
|
||
|
||
## Why
|
||
|
||
Сейчас после скачивания письма с IMAP (`mail_archive.py`) письмо сохраняется как
|
||
`email.md` (YAML-frontmatter + текст) и на этом всё. Пользователь не получает
|
||
сигнала о том, что пришло важное письмо: что в письме задача, встреча, срочный
|
||
вопрос или просто информация. Каждое письмо нужно вручную открывать и читать.
|
||
|
||
При этом инфраструктура уже есть:
|
||
- Radicale (CalDAV/CardDAV) на `cal.nixg.ru` — календари Личный/Рабочий/Задачи
|
||
- Vikunja (трекер задач) — развёрнут, ждёт администратора
|
||
- Ollama с Qwen3:8b — локальная модель (не уходит в облако, приватно)
|
||
- Мессенджер — уведомления можно слать в Telegram
|
||
|
||
Хочется: после скачивания письма локальная модель классифицирует его и помечает
|
||
тегами (информационное, требует срочного ответа, есть задача, назначена встреча
|
||
и т.п.), а на основе тегов запускаются обработчики: уведомление в мессенджер,
|
||
создание задачи в Vikunja, создание события в календаре Radicale.
|
||
|
||
Параллельно найден баг: вложения сейчас **не скачиваются** — `get_attachments()`
|
||
вызывает `himalaya attachment download --dir`, но правильный флаг `--downloads-dir`,
|
||
команда падает (exit 2), ошибка молча глотается `except: pass`, и папка
|
||
`attachments/` всегда пустая. Чейндж чинит это: вложения должны попадать в каталог
|
||
письма (что логично — каталог письма уже создаётся).
|
||
|
||
## What Changes
|
||
|
||
1. **Вложения скачиваются в каталог письма** — `mail_archive.py` правит вызов
|
||
`himalaya attachment download`: использует `--downloads-dir` вместо `--dir`,
|
||
кладёт файлы в `<msg_dir>/attachments/`. Проверяется на письме с вложением.
|
||
2. **Классификатор писем** — новый скрипт `email_classifier.py`, который:
|
||
- берёт неклассифицированные письма (нет `classification` в frontmatter)
|
||
- отдаёт текст письма локальной модели Qwen3:8b (Ollama localhost:11434)
|
||
- получает JSON с тегами: `info`, `urgent`, `task`, `meeting` (и, возможно,
|
||
`question`, `money`, `deadline`)
|
||
- пишет результат в frontmatter `email.md`: поле `classification` (тег) +
|
||
`classification_reason` (короткое обоснование)
|
||
3. **Обработчики по тегам** — новый скрипт `email_handlers.py`:
|
||
- `urgent` → уведомление в мессенджер (Telegram, через Hermes gateway)
|
||
- `task` → создание задачи в Vikunja (API tasks.nixg.ru)
|
||
- `meeting` → создание события в Radicale (календарь Рабочий, cal.nixg.ru)
|
||
- `info` → ничего, письмо просто помечено тегом
|
||
- идемпотентность: письмо обрабатывается один раз (трекинг в state/SQLite)
|
||
4. **Cron** — новый Hermes cron (или расширение существующего), который после
|
||
архивации запускает классификатор и обработчики.
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
- `email-classification`: классификация писем локальной LLM + теги в frontmatter
|
||
- `email-handlers`: подключение обработчиков (уведомление, задача, встреча) по тегам
|
||
- `email-attachments`: скачивание вложений письма в его каталог (фикс бага)
|
||
|
||
### Modified Capabilities
|
||
- (нет) — существующая capability `email-storage-format` не меняет требования
|
||
по формату файла, только добавляет новые поля; это расширение, а не изменение
|
||
существующих требований.
|
||
|
||
## Impact
|
||
|
||
- Скрипты: `mail_archive.py` (фикс вложений), новые `email_classifier.py`,
|
||
`email_handlers.py`
|
||
- Конфиг: Ollama (Qwen3:8b, уже есть), Vikunja API (нужен токен), Telegram
|
||
(gateway/уведомления), Radicale (события)
|
||
- Frontmatter `email.md`: новые поля `classification`, `classification_reason`,
|
||
`has_attachments` (если ещё нет)
|
||
- Cron: новый классификатор/обработчики
|