improve(email): format agent markdown responses as styled HTML emails
linuztx committed
Mar 23, 2026 at 09:54 UTC
85a9e988c28220552c3b5e3eb07a7ab2c491c662
1 file changed
+30
-2
plugins/_email_integration/helpers/smtp_client.py
+30
-2
@@ -47,10 +47,34 @@ async def send_reply(
47
loop = asyncio.get_event_loop()
48
49
def _sync_send():
50
- msg = MIMEMultipart() if attachments else MIMEText(body, "plain", "utf-8")
50
+ import markdown
51
+
52
+ html_body = markdown.markdown(body, extensions=['extra', 'nl2br'])
53
+ html_content = f"""
54
+ <html>
55
+ <head>
56
+ <style>
57
+ body {{ font-family: sans-serif; line-height: 1.5; }}
58
+ blockquote {{ border-left: 4px solid #ccc; margin: 0; padding-left: 1em; color: #666; }}
59
+ pre {{ background-color: #f6f8fa; padding: 1em; border-radius: 4px; overflow-x: auto; }}
60
+ code {{ font-family: monospace; background-color: #f6f8fa; padding: 0.2em 0.4em; border-radius: 3px; }}
61
+ pre code {{ padding: 0; background-color: transparent; }}
62
+ </style>
63
+ </head>
64
+ <body>
65
+ {html_body}
66
+ </body>
67
+ </html>
68
+ """
69
70
if attachments:
53
- msg.attach(MIMEText(body, "plain", "utf-8"))
71
+ msg = MIMEMultipart("mixed")
72
+
73
+ alt_part = MIMEMultipart("alternative")
74
+ alt_part.attach(MIMEText(body, "plain", "utf-8"))
75
+ alt_part.attach(MIMEText(html_content, "html", "utf-8"))
76
+ msg.attach(alt_part)
77
+
78
for filename, content in attachments:
79
part = MIMEBase("application", "octet-stream")
80
part.set_payload(content)
@@ -60,6 +84,10 @@ async def send_reply(
84
f"attachment; filename={filename}",
85
)
86
msg.attach(part)
87
+ else:
88
+ msg = MIMEMultipart("alternative")
89
+ msg.attach(MIMEText(body, "plain", "utf-8"))
90
+ msg.attach(MIMEText(html_content, "html", "utf-8"))
91
92
msg["From"] = config.username
93
msg["To"] = to