Expand description
BYOK SMTP email sink for self-host — an extracted Core capability crate.
The delivery leg for self-host alerts (budget/firewall policy alerts, monitor notifications) and, later, agent-inbox send. Delivery is “what runs” (Core), not policy (Gateway): the Gateway decides an alert fires; the node opens the socket and sends.
Nothing hardcoded: the transport is a swappable BYO SMTP relay resolved from
preferences (desktop Settings) first, then environment for headless setups.
There is no default provider — with no relay configured the sink is a no-op
(resolve_transport returns None) and callers simply skip email. SMTP is one
swappable sink; the SES agent-inbox path (packages/mail) is another.
The public sink is a rich builder (OutboundEmail) — multi-recipient,
cc/bcc/reply-to, text+html multipart, threading headers, and attachments — so
the agent-inbox send path (which needs all of that to preserve mail-client
threading) and the one-line alert path (send_email_alert) share one
transport.
Secret custody stays kernel-side: the SMTP password is never held here. Core
injects a resolver via set_password_resolver (backed by its smtp_auth
BYO-key store), so this crate has ZERO dependency on apps/core.
Structs§
- Attachment
- A file attached to an outbound email.
- Email
Transport Config - Non-secret SMTP transport config. The password is resolved separately via
[
crate::smtp_auth] so the secret surface stays isolated. - Outbound
Email - A fully-specified outbound email. Built once; the alert path wraps it.
- Transport
Prefs - The non-secret transport fields persisted under
SMTP_TRANSPORT_PREF_KEYand exchanged with the desktop SMTP card. The password never appears here.
Enums§
Constants§
- SMTP_
TRANSPORT_ PREF_ KEY - Preferences key holding the non-secret transport JSON (host/port/username/
from/starttls). The password is stored separately via [
crate::smtp_auth]. Core loads it on startup and on change so the desktop card takes effect with no restart.
Functions§
- apply_
transport_ prefs_ json - Apply a persisted
TransportPrefsJSON value to the in-process cache. Called at startup and whenever the pref changes. A malformed value clears the cache. - current_
transport_ prefs - Read the currently-cached non-secret transport prefs, if any (for
GET). - resolve_
transport - Resolve the effective transport: cached prefs first, else
RYU_SMTP_*env. ReturnsNonewhen no host or no password is available (email disabled). - send_
email - Send a fully-specified email over the given BYO SMTP transport. Returns the
Message-ID on success (for threading / provider-id records). Bounded by
[
SEND_TIMEOUT]. - send_
email_ alert - Thin single-recipient plain-text alert send over the given transport.
- set_
password_ resolver - Wire the SMTP-password resolver. Core calls this once at startup with a closure
over its
smtp_authstore. Idempotent replace. - set_
transport - Set (or clear, when
hostis empty) the in-process transport config from a preferences value. The password is set separately via [crate::smtp_auth::set_password].