Files
email_agent/.env.example
Paperclip Builder 7ca888f0c6 Phase 5: reply drafts — template/LLM draft, edit, SMTP send (AUD-71)
Implements Phase 5 of AGENTS.md §11 (FR-8, FR-15):

- Message detail pane (GET /partials/message) with body, recommended
  action, reply identity, template picker, editable draft, and history.
- internal/reply: OmniRoute (OpenAI-compatible) chat client and a
  template-based draft generator. All non-JEV models go through
  OmniRoute (§10).
- internal/mailops: SMTP send over smtp.gmail.com:587 with STARTTLS and
  the app password, forcing IPv4 (§9); FR-15 reply identity (send as the
  arrived-at X-Pm-Original-To address, else "Sam Rolfe"); threading via
  In-Reply-To/References; -check-smtp safe verification; and a
  [Gmail]/Sent Mail thread check.
- Migration v5 stores messages.message_id_header and drafts.sent_at;
  mailfetch parses Message-ID.
- Send is user-triggered only: CSRF + UI confirm + confirm=yes guard,
  no auto-send, duplicate-send refused. A sent reply files the original
  under Replied-to/<address> and logs every step (FR-13).
- Tests for reply, mailops SMTP/identity/thread check, store drafts and
  migration v5, and the server draft/edit/send guards.
- docs/phase5-replies.md, README, .env.example, docker-compose updated.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-11 22:05:35 +11:00

53 lines
2.1 KiB
Plaintext

# Email Agent — environment variable names (values are NOT committed).
#
# Copy to `.env` for local Docker Compose use. In production these come from
# ~/.config/environment.d/10-secrets.conf (or the host environment) and are
# passed through by docker-compose.
#
# Secret values must never be committed to git.
# --- Runtime ---------------------------------------------------------------
EMAIL_AGENT_ENV=production
EMAIL_AGENT_PORT=8790
EMAIL_AGENT_ADDR=:8790
EMAIL_AGENT_DB_PATH=/data/email_agent.db
EMAIL_AGENT_LOG_LEVEL=info
EMAIL_AGENT_PUBLIC_BASE_URL=https://mail.lab.audasmedia.com.au
# --- Session / auth --------------------------------------------------------
# Session cookie signing key. Generate with: python3 -c 'import secrets;print(secrets.token_hex(32))'
EMAIL_AGENT_SESSION_SECRET=change-me
# Login password for the single user (Sam). If unset, the session secret above
# doubles as the password.
EMAIL_AGENT_PASSWORD=
# --- Gmail IMAP (Phase 2) ---------------------------------------------------
# App password only (AGENTS.md §9). Values live in the host environment, never here.
GMAIL_USER=
GMAIL_APP_PASSWORD=
EMAIL_AGENT_IMAP_HOST=imap.gmail.com
EMAIL_AGENT_IMAP_PORT=993
EMAIL_AGENT_IMAP_LOOKBACK_DAYS=14
EMAIL_AGENT_IMAP_MAX_MESSAGES=100
# --- Gmail SMTP (Phase 5 replies) -------------------------------------------
# Submission uses STARTTLS on 587 and forces IPv4, like IMAP.
EMAIL_AGENT_SMTP_HOST=smtp.gmail.com
EMAIL_AGENT_SMTP_PORT=587
# --- Integrations (used from later phases) ---------------------------------
# JEV is the TypeSafe System One HTTP API. JEV_BASE_URL defaults to the
# documented host https://api.typesafe.ai when unset.
JEV_BASE_URL=
JEV_API_KEY=
JEV_MODEL=jev-latest
# Classifier bounds (FR-3): in-flight JEV requests, and messages per run.
EMAIL_AGENT_CLASSIFY_CONCURRENCY=4
EMAIL_AGENT_CLASSIFY_MAX_MESSAGES=200
# OmniRoute is the house AI gateway; all non-JEV models go through it. The
# default base URL is the gateway on .13 (http://192.168.20.13:20129/v1).
OMNIROUTE_BASE_URL=
OMNIROUTE_API_KEY=
OMNIROUTE_MODEL=auto/best-chat
HUB_TOKEN=