Skip to content

feat: HTML email delivery for cron jobs and send_message - #34603

Closed
fstolze wants to merge 1 commit into
NousResearch:mainfrom
fstolze:feat/html-email-cron-delivery
Closed

feat: HTML email delivery for cron jobs and send_message#34603
fstolze wants to merge 1 commit into
NousResearch:mainfrom
fstolze:feat/html-email-cron-delivery

Conversation

@fstolze

@fstolze fstolze commented May 29, 2026

Copy link
Copy Markdown

Three coordinated changes so HTML content flows end-to-end through cron delivery and send_message:

  • cron/scheduler.py — detect HTML in job output, skip plain-text wrapper to preserve the doctype, allow cron jobs to set email subject via job name (with {date} substitution), and forward email_subject through both live adapter and standalone send paths.
  • gateway/platforms/email.py — when content starts with <!doctype html or <html, send as multipart/alternative with plain-text fallback. Strip <style> and <head> blocks in the fallback. Respect explicit subject from metadata. Fresh HTML emails omit threading headers so they appear as their own thread in Gmail.
  • tools/send_message_tool.py — same HTML detection + multipart/alternative logic in the standalone SMTP path. Strip preamble text before the doctype. Accept optional email_subject parameter.

Three coordinated changes so HTML content flows end-to-end:

cron/scheduler.py: detect HTML in job output, skip plain-text wrapper
to preserve the doctype, allow cron jobs to set email subject via
job name (with {date} substitution), and forward email_subject
through both live adapter and standalone send paths.

gateway/platforms/email.py: when content starts with <!doctype html
or <html, send as multipart/alternative with plain-text fallback.
Strip <style> and <head> blocks in the fallback. Respect explicit
subject from metadata. Fresh HTML emails omit threading headers
so they appear as their own thread in Gmail.

tools/send_message_tool.py: same HTML detection + multipart/alternative
logic in the standalone SMTP path. Strip preamble text before the
doctype. Accept optional email_subject parameter.
@alt-glitch alt-glitch added type/feature New feature or request comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery platform/email Email (IMAP/SMTP) adapter P3 Low — cosmetic, nice to have labels May 29, 2026
@vincentee91g

Copy link
Copy Markdown

Thanks for adding the subject plumbing here — this is a big improvement for outbound mail.

One thing I filed separately as #46947: the cron email_subject is gated on is_html, so plain-text cron deliveries (and plain-text send_message) still fall through to the hardcoded Re: Hermes Agent / Hermes Agent in _send_email, even though the job name is already available in the Cronjob Response: <name> wrapper. Details + a suggested generalization are in the issue. Happy to send a follow-up PR for the plain-text path if you'd prefer to keep this one scoped to HTML.

@fstolze

fstolze commented Jun 16, 2026

Copy link
Copy Markdown
Author

Thanks for adding the subject plumbing here — this is a big improvement for outbound mail.

One thing I filed separately as #46947: the cron email_subject is gated on is_html, so plain-text cron deliveries (and plain-text send_message) still fall through to the hardcoded Re: Hermes Agent / Hermes Agent in _send_email, even though the job name is already available in the Cronjob Response: <name> wrapper. Details + a suggested generalization are in the issue. Happy to send a follow-up PR for the plain-text path if you'd prefer to keep this one scoped to HTML.

Yes, that would be great. Also thanks for filing the bug report!

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the HTML-email delivery work. The underlying behavior is still present on current main, but this branch predates the email-plugin migration and needs a targeted salvage.

Problems

  • gateway/platforms/email.py in this PR was moved by 5600105478ffde29d7566b45421b100eaa29c4ef; current outbound code is plugins/platforms/email/adapter.py:893-962 and :1190-1230. Current tools/send_message_tool.py:1067-1068 routes standalone email through the registry, so the proposed direct _send_email wiring no longer reaches the live sender.
  • The diff adds an internal email_subject argument but does not add a field to SEND_MESSAGE_SCHEMA (tools/send_message_tool.py:197-234) or extract it in _handle_send (:354-460), so send_message callers cannot supply the claimed subject.
  • The PR adds no tests; current tests/gateway/test_email.py:845-856 still asserts the problematic fresh-recipient default.

Suggested changes

  • Port both live and standalone behavior to plugins/platforms/email/adapter.py, retaining registry routing.
  • Add and propagate a schema-level email_subject, then cover HTML MIME parts, explicit subject/fresh-thread behavior, and cron delivery with focused tests.

Automated hermes-sweeper review.

@@ -554,7 +554,7 @@ async def _send_via_adapter(
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This only adds an internal parameter: the PR does not add email_subject to SEND_MESSAGE_SCHEMA or extract it in _handle_send, so send_message callers cannot provide the subject described in the PR. Please wire the public argument through the actual send path.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages 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 13, 2026
@swissly

swissly commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Overlap note (2026-08-03): this PR addresses the same topic (HTML email delivery). PR #73294 (swissly) consolidates Markdown-to-HTML rendering for ALL 4 send paths + allowlist sanitizer + 20 tests, and was just rebased onto current main (commit 9529ee30). Please review #73294 for consolidation rather than duplicating send-path fixes.

@fstolze fstolze closed this Aug 3, 2026
@fstolze
fstolze deleted the feat/html-email-cron-delivery branch August 3, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management 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.

5 participants