Skip to content

v0.67.0 — Email adapter (IMAP/SMTP + Gmail)

Latest

Choose a tag to compare

@ertad-family ertad-family released this 04 Jun 19:41

Email adapter — an agent's mail senses & hands

Mail joins the modality set: read a mailbox, perceive new mail as it arrives (sense), and send — over raw IMAP/SMTP or the Gmail API.

Raw IMAP/SMTP — no new dependency

  • IMAPDriver (scheme=imap): fetch reads a mailbox by UID cursor; sense delta-polls for new mail (UID > cursor, modality="message").
  • SMTPDriver (scheme=smtp): write composes a MIME message (to/cc/bcc/html/reply_to) and sends it.
  • Runs the stdlib imaplib/smtplib in asyncio.to_thread — the event loop never blocks, app-password auth needs nothing extra.
  • EmailDiscovery: imap:// → a read+sense endpoint per mailbox; smtp:// → an /outbox send endpoint.

OAuth2 (XOAUTH2)

  • Reusable OAuth2TokenProvider (liquid.auth.oauth2) factored out of the HTTP flow so the mail sockets reuse the same refresh + vault-storage outside httpx; refresh-once-and-retry on auth failure.
  • auth_scheme threaded into WriteContext/SenseContext (mirroring FetchContext) so any non-HTTP driver sees the scheme on write/sense.

Gmail REST

  • GmailDriver (scheme=gmail): fetch lists + hydrates messages, write posts a base64url MIME to messages.send, sense delta-polls history.list. Rides the shared httpx client + the OAuth2 httpx.Auth the Fetcher already builds (401 refresh for free).
  • gmail://me@host/messages (read+sense) + /messages/send (write), oauth2 / tier-A.

Surface parity holds automatically: mail read endpoints emit list_/sense_ tools via to_tools(); send surfaces through liquid_execute.

Real-world reach now also: email (IMAP/SMTP + Gmail).