115 lines
3.7 KiB
Markdown
115 lines
3.7 KiB
Markdown
---
|
|
title: Email Agent — Family Inbox Triage
|
|
type: project
|
|
status: active
|
|
created: "2026-10-13 10:45"
|
|
updated: "2026-09-26"
|
|
tags:
|
|
- tool
|
|
- project
|
|
- email
|
|
- family
|
|
- architecture
|
|
- go
|
|
- inbox
|
|
- triage
|
|
- gmail
|
|
- htmx
|
|
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.
|