Files

69 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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: новый классификатор/обработчики