feat: add email_send orchestrator tool
Wraps the existing email_utils.send_email helper as an admin-only tool. Accepts to, subject, body (plain text); newlines converted to <br> for HTML part. Registered in _CALLABLES, _ALL_DECLARATIONS, and TOOL_ROLES (admin). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -48,7 +48,7 @@ from tools.scratch import (
|
|||||||
from tools.system import cortex_restart as _cortex_restart, cortex_logs as _cortex_logs
|
from tools.system import cortex_restart as _cortex_restart, cortex_logs as _cortex_logs
|
||||||
from tools.web import http_fetch as _http_fetch
|
from tools.web import http_fetch as _http_fetch
|
||||||
from tools.files import file_list as _file_list, file_write as _file_write
|
from tools.files import file_list as _file_list, file_write as _file_write
|
||||||
from tools.notify import nc_talk_send as _nc_talk_send
|
from tools.notify import nc_talk_send as _nc_talk_send, email_send as _email_send
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -296,6 +296,7 @@ _CALLABLES: dict[str, callable] = {
|
|||||||
"cortex_restart": _cortex_restart,
|
"cortex_restart": _cortex_restart,
|
||||||
"cortex_logs": _cortex_logs,
|
"cortex_logs": _cortex_logs,
|
||||||
"http_fetch": _http_fetch,
|
"http_fetch": _http_fetch,
|
||||||
|
"email_send": _email_send,
|
||||||
"nc_talk_send": _nc_talk_send,
|
"nc_talk_send": _nc_talk_send,
|
||||||
"task_list": _task_list,
|
"task_list": _task_list,
|
||||||
"task_create": _task_create,
|
"task_create": _task_create,
|
||||||
@@ -755,6 +756,24 @@ _file_write_declaration = types.FunctionDeclaration(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_email_send_declaration = types.FunctionDeclaration(
|
||||||
|
name="email_send",
|
||||||
|
description=(
|
||||||
|
"Send an email from the server's configured SMTP account. Use for delivering "
|
||||||
|
"summaries, reports, reminders, or any content the user wants emailed. "
|
||||||
|
"body is plain text; newlines are preserved."
|
||||||
|
),
|
||||||
|
parameters=types.Schema(
|
||||||
|
type=types.Type.OBJECT,
|
||||||
|
properties={
|
||||||
|
"to": types.Schema(type=types.Type.STRING, description="Recipient email address"),
|
||||||
|
"subject": types.Schema(type=types.Type.STRING, description="Email subject line"),
|
||||||
|
"body": types.Schema(type=types.Type.STRING, description="Plain-text email body"),
|
||||||
|
},
|
||||||
|
required=["to", "subject", "body"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
_nc_talk_send_declaration = types.FunctionDeclaration(
|
_nc_talk_send_declaration = types.FunctionDeclaration(
|
||||||
name="nc_talk_send",
|
name="nc_talk_send",
|
||||||
description=(
|
description=(
|
||||||
@@ -791,6 +810,8 @@ TOOL_ROLES: dict[str, str] = {
|
|||||||
"file_list": "admin",
|
"file_list": "admin",
|
||||||
"file_write": "admin",
|
"file_write": "admin",
|
||||||
"ae_task_list": "admin", # reads agents_sync kanban
|
"ae_task_list": "admin", # reads agents_sync kanban
|
||||||
|
"email_send": "admin", # sends from server SMTP account
|
||||||
|
"nc_talk_send": "admin",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Tools that require explicit user confirmation before executing.
|
# Tools that require explicit user confirmation before executing.
|
||||||
@@ -831,6 +852,7 @@ _ALL_DECLARATIONS: list[types.FunctionDeclaration] = [
|
|||||||
_cortex_restart_declaration,
|
_cortex_restart_declaration,
|
||||||
_cortex_logs_declaration,
|
_cortex_logs_declaration,
|
||||||
_http_fetch_declaration,
|
_http_fetch_declaration,
|
||||||
|
_email_send_declaration,
|
||||||
_nc_talk_send_declaration,
|
_nc_talk_send_declaration,
|
||||||
_task_list_declaration,
|
_task_list_declaration,
|
||||||
_task_create_declaration,
|
_task_create_declaration,
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
Notification tools — proactively send messages to user channels.
|
Notification tools — proactively send messages to user channels.
|
||||||
|
|
||||||
nc_talk_send routes through notification.py → channels.json.
|
nc_talk_send routes through notification.py → channels.json.
|
||||||
Requires notification_channel and notification_room set in the user's channels.json.
|
email_send uses the server SMTP config from .env (smtp_server, smtp_from_*).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from persona import get_user
|
from persona import get_user
|
||||||
@@ -12,6 +13,21 @@ from persona import get_user
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def email_send(to: str, subject: str, body: str) -> str:
|
||||||
|
"""Send an email via the server's configured SMTP account."""
|
||||||
|
from email_utils import send_email
|
||||||
|
ok = await asyncio.to_thread(
|
||||||
|
send_email,
|
||||||
|
to_email=to,
|
||||||
|
subject=subject,
|
||||||
|
body_text=body,
|
||||||
|
body_html=body.replace("\n", "<br>"),
|
||||||
|
)
|
||||||
|
if ok:
|
||||||
|
return f"Email sent to {to}."
|
||||||
|
return "Failed to send email — check SMTP configuration in .env."
|
||||||
|
|
||||||
|
|
||||||
async def nc_talk_send(message: str) -> str:
|
async def nc_talk_send(message: str) -> str:
|
||||||
"""Send a message to the user via their configured notification channel.
|
"""Send a message to the user via their configured notification channel.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user