Skip to content

fix(email): support send-only gateway mode - #57605

Open
petrakersten wants to merge 2 commits into
NousResearch:mainfrom
petrakersten:fix/email-send-only-agentmail-upstream
Open

petrakersten wants to merge 2 commits into
NousResearch:mainfrom
petrakersten:fix/email-send-only-agentmail-upstream

Conversation

@petrakersten

@petrakersten petrakersten commented Jul 3, 2026

Copy link
Copy Markdown

Summary

  • add platforms.email.mode: send_only / SMTP-only mode so Hermes can send cron/system emails without starting IMAP polling
  • respect explicit platforms.email.enabled: false instead of env credentials re-enabling the email adapter

Relationship to other PRs

Test Plan

  • scripts/run_tests.sh tests/gateway/test_email.py tests/gateway/test_session_reset_notify.py -q

@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch from b3c3ef5 to 9f5bb8f Compare July 3, 2026 08:35
@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery platform/email Email (IMAP/SMTP) adapter area/config Config system, migrations, profiles P3 Low — cosmetic, nice to have sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Jul 3, 2026
@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch from 9f5bb8f to e4cd8db Compare July 3, 2026 08:38
@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch from e4cd8db to df0b610 Compare July 9, 2026 05:24

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for splitting the SMTP-only work from #53264. The current main path still requires IMAP and starts polling, so the feature addresses a real gap.

Problems

  • plugins/platforms/email/adapter.py:172 relaxes the plugin requirement for every SMTP-only environment. In the registry enable pass, gateway/config.py:2185-2249 combines EmailAdapter._is_connected() accepting an address (plugins/platforms/email/adapter.py:1239-1247) with that relaxed requirement and enables Email even when no send-only mode was selected. Normal-mode connect() still requires IMAP (plugins/platforms/email/adapter.py:556-581), producing a configured-but-fatal adapter instead of preserving prior disabled behavior.
  • The new user-facing mode is undocumented. website/docs/user-guide/messaging/email.md:24-28 still makes IMAP a prerequisite and lines 65-82 list it as required.

Suggested changes

  • Gate SMTP-only enablement on the resolved send-only config, and add coverage for SMTP-only credentials without that mode.
  • Add an end-to-end config-loader test and document the mode in the Email guide.

Automated hermes-sweeper review.

Comment thread plugins/platforms/email/adapter.py Outdated
"""
addr = os.getenv("EMAIL_ADDRESS", "").strip()
pwd = os.getenv("EMAIL_PASSWORD", "").strip()
imap = os.getenv("EMAIL_IMAP_HOST", "").strip()
smtp = os.getenv("EMAIL_SMTP_HOST", "").strip()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This broadens the plugin gate for every SMTP-only environment, not just send-only configs. The registry enable pass then sees Email's address-only is_connected predicate and enables normal mode; normal connect() still requires IMAP and fails. Make the enablement predicate configuration-aware so SMTP-only credentials require resolved send_only mode.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch from df0b610 to 036fd08 Compare July 25, 2026 21:44
@petrakersten

Copy link
Copy Markdown
Author

Addressed the sweeper findings in the current head 036fd08c2: send-only enablement is now gated on the resolved Email mode, SMTP credentials without send-only remain disabled, config-loader coverage was added, and the Email guide documents the mode. Fresh verification: git diff --check clean; pytest tests/gateway/test_email.py -q → 93 passed.

@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch 2 times, most recently from 95f3c5e to c92169d Compare August 2, 2026 18:18
@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch 2 times, most recently from 99736ae to 2f4f995 Compare August 15, 2026 18:18
@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference, author can ignore or act on any point.

fix(email): support send-only gateway mode

  1. plugins/platforms/email/adapter.py:230-241check_email_requirements() now returns True for SMTP-only credentials. A partial setup (SMTP configured, no IMAP, no mode: send_only) now creates the adapter, and connect() fails with a retryable "missing EMAIL_IMAP_HOST" → the reconnect watcher retries indefinitely with a fatal code, instead of the platform staying cleanly disabled. Consider having check_email_requirements require IMAP unless send-only mode is explicitly set, so the adapter isn't present until the operator opts into the mode.

  2. The send-only alias set (send_only/send-only/smtp_only/smtp-only/outbound_only/outbound-only) is parsed in three places — gateway/config.py:_enable_from_env, adapter __init__, and _is_connected — with identical sets that can drift (and delivery_mode is honored in some but not all paths). Extracting a shared _is_send_only(extra) helper would keep the three sites consistent.

  3. plugins/platforms/email/adapter.py:1494-1520_is_connected resolves password only from env (EMAIL_PASSWORD) while address/smtp/imap fall back to extra. If a PlatformConfig ever carries the password in extra, _is_connected would report disconnected for a configured adapter. Minor inconsistency; resolving password from extra too (or documenting that it must be env-only) would make the resolution uniform.

The explicit-disable test (test_email_explicit_disable_not_reenabled_by_env) correctly covers the _enabled_explicit guard, and the send-only connect test asserting _poll_task is None is the right invariant.

@petrakersten

Copy link
Copy Markdown
Author

Addressed the latest automated review in head e7a7e69cf: send-only alias parsing is now centralized and shared by config enablement, adapter construction, and connected-state checks; config-only passwords are also honored by the connected-state check, with alias/config-only regression coverage. The SMTP-only-without-explicit-mode case remains cleanly disabled by _apply_env_overrides and _is_connected, so the adapter is not started merely because check_fn reports the bundled plugin is available. Fresh verification: git diff --check clean; pytest tests/gateway/test_email.py -q → 49 passed, 3 subtests passed. GitHub readback matches the pushed head and reports mergeable=true; blocked remains maintainer review/approval.

@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch 2 times, most recently from ea6e56a to 08640c8 Compare September 2, 2026 18:20
@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch from 08640c8 to 90390de Compare September 7, 2026 18:21
@petrakersten
petrakersten force-pushed the fix/email-send-only-agentmail-upstream branch from 90390de to c196109 Compare September 12, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have platform/email Email (IMAP/SMTP) adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants