Nothing open on GitHub. Fix merged in #16568. Check it covers your case.
The short answer
- Known?
- Yes. 5 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #16568. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
resolved, deciding PR #16568. That is separate from the fix event. - Still open
- Nothing open on GitHub.
Multiple fixes and a bug report addressing the absence of a required Date header in outbound emails, which caused messages to be bounced by mail filters. Several parallel or iterative PRs target different code paths where the header was missing.
Open issues0
Open PRs0
Fixes on record
-
#16568 fix(email): add required Date header to outbound mail (salvage #15164)
files:
gateway/platforms/email.py,scripts/release.py,tests/gateway/test_email.py,tools/send_message_tool.pyShow the diff
-
gateway/platforms/email.py@@ -28,6 +28,7 @@ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase +from email.utils import formatdate from email import encoders from pathlib import Path from typing import Any, Dict, List, Optional @@ -504,6 +505,7 @@ def _send_email( msg["In-Reply-To"] = original_msg_id msg["References"] = original_msg_id + msg["Date"] = formatdate(localtime=True) msg_id = f"<hermes-{uuid.uuid4().hex[:12]}@{self._address.split('@')[1]}>" msg["Message-ID"] = msg_id @@ -586,6 +588,7 @@ def _send_email_with_attachment( msg["In-Reply-To"] = original_msg_id msg["References"] = original_msg_id + msg["Date"] = formatdate(localtime=True) msg_id = f"<hermes-{uuid.uuid4().hex[:12]}@{self._address.split('@')[1]}>" msg["Message-ID"] = msg_id -
scripts/release.py@@ -53,6 +53,7 @@ "[redacted:email]": "say8hi", "[redacted:email]": "web3blind", "[redacted:email]": "alexg0bot", + "[redacted:email]": "scheidti", "[redacted:email]": "benjaminsehl", "[redacted:email]": "Nerijusas", "[redacted:email]": "Ito-69", -
tests/gateway/test_email.py@@ -488,6 +488,7 @@ def test_reply_uses_re_prefix(self): self.assertEqual(send_call["Subject"], "Re: Project question") self.assertEqual(send_call["In-Reply-To"], "<[redacted:email]>") self.assertEqual(send_call["References"], "<[redacted:email]>") + self.assertIn("Date", send_call) def test_reply_does_not_double_re(self): """If subject already has Re:, don't add another.""" @@ -519,6 +520,7 @@ def test_no_thread_context_uses_default_subject(self): send_call = mock_server.send_message.call_args[0][0] self.assertEqual(send_call["Subject"], "Re: Hermes Agent") + self.assertIn("Date", send_call) class TestSendMethods(unittest.TestCase): @@ -889,6 +891,11 @@ def test_send_email_tool_success(self): self.assertEqual(result["platform"], "email") _, kwargs = mock_server.starttls.call_args self.assertIsInstance(kwargs["context"], ssl.SSLContext) + send_call = mock_server.send_message.call_args[0][0] + self.assertEqual(send_call["Subject"], "Hermes Agent") + self.assertIn("Date", send_call) + self.assertEqual(send_call["To"], "[redacted:email]") + self.assertEqual(send_call["From"], "[redacted:email]") @patch.dict(os.environ, { "EMAIL_ADDRESS": "[redacted:email]", -
tools/send_message_tool.py@@ -1075,6 +1075,7 @@ async def _send_email(extra, chat_id, message): """Send via SMTP (one-shot, no persistent connection needed).""" import smtplib from email.mime.text import MIMEText + from email.utils import formatdate address = extra.get("address") or os.getenv("EMAIL_ADDRESS", "") password = [redacted:secret-assignment]"EMAIL_PASSWORD", "") @@ -1092,6 +1093,7 @@ async def _send_email(extra, chat_id, message): msg["From"] = address msg["To"] = chat_id msg["Subject"] = "Hermes Agent" + msg["Date"] = formatdate(localtime=True) server = smtplib.SMTP(smtp_host, smtp_port) server.starttls(context=ssl.create_default_context())
-
-
#19646 fix(cli,email): quoted-relative file-drop paths + Date header on tool email path
files:
cli.py,tools/send_message_tool.pyShow the diff
-
cli.py@@ -1505,6 +1505,10 @@ def _detect_file_drop(user_input: str) -> "dict | None": or stripped.startswith('"~') or stripped.startswith("'/") or stripped.startswith("'~") + or stripped.startswith('"./') + or stripped.startswith('"../') + or stripped.startswith("'./") + or stripped.startswith("'../") or (len(stripped) >= 4 and stripped[0] in ("'", '"') and stripped[2] == ":" and stripped[3] in ("\\", "/") and stripped[1].isalpha()) ) if not starts_like_path: -
tools/send_message_tool.py@@ -10,9 +10,10 @@ import logging import os import re -from typing import Dict, Optional import ssl import time +from email.utils import formatdate +from typing import Dict, Optional from agent.redact import redact_sensitive_text
-
2 PRs closed without merging
From the close comments: merged via another change 1 · superseded by another PR 1
Closed issues · 1
- Closed#15160[Bug]: Outbound Hermes emails missing Date header — bounced by mail filter
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.40: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the Lab