Files
hermes 7550aff102 feat: классификация писем Qwen3:8b + обработчики (urgent→TG, task→VTODO, meeting→VEVENT)
- mail_archive.py: фикс вложений himalaya --dir → --downloads-dir; attachments/ только при has_attachment; идемпотентно
- email_classifier.py: Qwen3:8b (Ollama) → теги info/urgent/task/meeting в frontmatter email.md
- email_handlers.py: urgent→Telegram (Bot API+SOCKS5), task→Radicale VTODO, meeting→Radicale VEVENT; handled_* идемпотентность; --dry-run
- .gitignore: игнор *.env.bak*
- openspec: чейндж email-classification-handlers (в работе)
- STATUS/TODO/WALKTHROUGH: прогресс сессии, подводные камни Radicale (http.client, Depth:1, формат дат)
2026-09-13 20:35:58 +00:00

4.1 KiB
Raw Permalink Blame History

PRD — Email Assistant (локальный почтовый ассистент)

Обновлено: 2026-09-13

Цель

Инкрементальный локальный архив корпоративной почты с последующей обработкой локальной LLM: классификация писем, извлечение контактов, дайджесты, интеграция с локальным календарём/задачами (Radicale CalDAV). Всё — локально (bigbox), без облачных зависимостей.

Пользователи

Один пользователь — estorozhenko (личная корпоративная почта e.storozhenko@vinogorod.ru, IMAP mail.corpoffice.tech).

Функциональные требования

  1. Архивация: скачивать письма с IMAP, сохранять текст+метаданные в email.md (YAML-frontmatter + текст), структура /opt/hermes/email/<folder>/YYYY/MM/<uid>/.
  2. Вложения: сохранять вложения в каталог письма attachments/ (ФТ-2, в работе).
  3. Поиск: SQLite FTS5 по письмам (веб-интерфейс, Задача 1).
  4. Классификация: локальная LLM (Qwen3:8b) классифицирует письмо → тег info/urgent/task/meeting + обоснование (ФТ-3, в работе).
  5. Обработчики: по тегам — urgent→Telegram, task→Radicale VTODO (календарь «Задачи»), meeting→Radicale VEVENT (календарь «Рабочий»), info→ничего (ФТ-4, в работе).
  6. Контакты: извлечение контактов из подписей через LLM + двухсторонний CardDAV sync с Radicale («Контакты»).
  7. Дайджест: еженедельная сводка писем.
  8. Календарь/задачи: Radicale CalDAV (Личный/Рабочий/Задачи), синхронизация с Android (DAVx5 → календари/контакты, jtx board → VTODO-задачи).

Нефункциональные требования

  • Приватность: текст писем никогда не покидает bigbox (обработка только локальной LLM Qwen3:8b через Ollama localhost:11434).
  • Идемпотентность: повторный запуск не дублирует (классификацию, обработчики, вложения).
  • Отказоустойчивость: сбой обработчика не теряет письмо (лог + повторная попытка по тегу).
  • Расположение: всё в /opt/hermes/ (единый каталог, бэкап = копия).
  • Порядок данных: секреты — только в .env/.htpasswd, не в git и не в README/WALKTHROUGH.

Границы (что НЕ делаем)

  • НЕ используем облачных ассистентов/API для содержимого писем (Nylas и т.п. отклонено).
  • НЕ используем Vikunja — задачи через Radicale VTODO (решение 2026-09-13).
  • НЕ отправка почты (архив read-only).
  • НЕ удаляем/теряем письма — архив только пополняется.

Критерии готовности

  • Вложения качаются в attachments/ (ФТ-2)
  • Классификатор проставляет теги на всю базу (ФТ-4)
  • Обработчики срабатывают и видны в Telegram/Radicale (ФТ-5)
  • Веб-интерфейс: поиск, тэги, «Создать задачу» (Задача 1)
  • Календарь/задачи синхронизируются на Android по CalDAV

Стек

Himalaya CLI → Python (mail_archive.py) → SQLite FTS5 → Ollama Qwen3:8b → Radicale (CalDAV/CardDAV, docker :5232, cal.nixg.ru) → Telegram (уведомления).