Files
obsidian-vault/010 inbox/Email Agent — Family Inbox Triage.md

124 lines
3.8 KiB
Markdown

---
type: note
proposed_folder: 200 projects/Tools Software WebUI
proposed_toc: "100 Table of Contents/Projects.md → Tools & Software"
proposed_tags:
- tool
- project
- email
- family
- architecture
- go
- inbox
- triage
- gmail
- htmx
confidence: 0.82
approved: false
proposed_for: ad82cc944024
created: "2026-10-13 10:45"
tags:
- project
- email
- gmail
- go
- htmx
- ai
aliases:
- Email Agent
- Family Inbox Triage
skills:
- Go backend development
- HTMX server-rendered UI
- IMAP and SMTP integration
- LLM classification (JEV) and drafting (OmniRoute)
- SQLite data modelling
- Docker and Caddy deployment
tools:
- Go
- HTMX
- SQLite
- Gmail IMAP/SMTP
- JEV (TypeSafe System One)
- OmniRoute
- Apprise
- Docker
- Caddy
---
# [[Email Agent — Family Inbox Triage]]
## What is this project?
One page that clears the family inbox. All family mail lands in a single Gmail
account, because PurelyMail forwards every domain address there. This app reads
that mail, sorts it into categories, recommends what to do, and lets Sam act on
whole groups at once.
The goal is simple: Sam opens one page, spends a few minutes, and knows that
nothing important was missed.
## What it does
- **Reads Gmail** over IMAP with an app password. It forces IPv4, because IPv6
to Gmail is broken from the server.
- **Classifies every message** with JEV (a TypeSafe System One model). Each mail
gets a category, an importance, a suggested action, and a confidence.
- **Shows a triage list** grouped by category, with the recommended action on
every row and a bulk select.
- **Acts in bulk**: delete, move, or mark. Deletes are recoverable — the app
moves mail to a Delete label, never hard-deletes.
- **Drafts replies** with an LLM through OmniRoute, from a template or a rule.
Sam edits the draft, then sends. It sends as the address the mail arrived at,
and there is no auto-send.
- **Spotlights unsubscribe links** and keeps an ignore list. It never follows a
link by itself.
- **Has a rules editor** — plain text, saved and versioned. The classifier obeys
the rules.
- **Sends a daily summary** by email through Apprise.
- **Answers the Hub**: a read-only question like "anything important in my
inbox?" returns a short answer.
## Why it matters (what it shows)
This is an end-to-end private AI tool, built and run in the home lab. It shows a
full path from an idea to a deployed service: a Go backend with no heavyweight
framework, an HTMX interface with no build step, a small SQLite store, real
mail-server protocols (IMAP and SMTP with an app password), two different model
paths (JEV for typed judgement, OmniRoute for text), and a strict "the human
confirms every action" design.
The design keeps the risky actions safe: no auto-send, no auto-delete, every
action logged, and deletes recoverable.
## Architecture
```mermaid
flowchart LR
SAM["Sam<br/>phone or desktop"] --> CADDY["Caddy on .35"]
CADDY --> UI["HTMX dashboard<br/>:8790"]
UI --> DB[("SQLite")]
UI --> GMAIL["Gmail<br/>IMAP + SMTP, IPv4"]
UI --> JEV["JEV<br/>classify"]
UI --> OMNI["OmniRoute<br/>draft reply"]
UI --> APPRISE["Apprise<br/>summary email"]
HUB["Central AI Hub :8788"] --> API["Hub API<br/>/ask /capabilities"]
API --> DB
N8N["n8n schedule"] --> JOBS["CLI jobs"]
JOBS --> DB
```
## Where it lives
- **Code**: Gitea repo `sam/email_agent`.
- **Live**: `https://mail.lab.audasmedia.com.au` (container on `.13`, port 8790).
- **Interactive map**: https://maps.lab.audasmedia.com.au/email_agent/docs/
- **AI context**: Outline collection `Email Agent`.
- **Tasks**: Vikunja project `Email Agent`.
## Status
Built and deployed. Phases 1 to 7 of the build spec are done and running. The
Phase 8 documentation pass wrote this note, the Gitea README and docs, the
Outline collection, the Vikunja board, and the architecture map.