fix(tools): point email home-channel error at EMAIL_HOME_ADDRESS
The no-home-channel error for send_message derived the env var name generically as <PLATFORM>_HOME_CHANNEL, producing EMAIL_HOME_CHANNEL for the email platform. But gateway/config.py reads EMAIL_HOME_ADDRESS, so a user following the error's guidance would set a variable that is never consulted. Add a per-platform override map so the email hint names the variable actually read; all other platforms keep the generic hint.
This commit is contained in:
@ -1256,6 +1256,54 @@ class TestParseTargetRefEmail:
|
||||
assert _parse_target_ref("slack", "user@example.com")[2] is False
|
||||
|
||||
|
||||
class TestEmailHomeChannelErrorHint:
|
||||
"""The no-home-channel error for email points at the real env var.
|
||||
|
||||
Email reads its home channel from EMAIL_HOME_ADDRESS (gateway/config.py),
|
||||
not the generic EMAIL_HOME_CHANNEL. The error guidance must name the
|
||||
variable that is actually consulted so users who follow it succeed.
|
||||
"""
|
||||
|
||||
def test_email_error_names_email_home_address(self):
|
||||
email_cfg = SimpleNamespace(enabled=True, token="", extra={})
|
||||
config = SimpleNamespace(
|
||||
platforms={Platform.EMAIL: email_cfg},
|
||||
get_home_channel=lambda _platform: None,
|
||||
)
|
||||
with patch("gateway.config.load_gateway_config", return_value=config), \
|
||||
patch("tools.interrupt.is_interrupted", return_value=False):
|
||||
result = json.loads(
|
||||
send_message_tool(
|
||||
{
|
||||
"action": "send",
|
||||
"target": "email",
|
||||
"message": "hi",
|
||||
}
|
||||
)
|
||||
)
|
||||
assert "EMAIL_HOME_ADDRESS" in result["error"]
|
||||
assert "EMAIL_HOME_CHANNEL" not in result["error"]
|
||||
|
||||
def test_non_email_platform_keeps_generic_home_channel_hint(self):
|
||||
telegram_cfg = SimpleNamespace(enabled=True, token="***", extra={})
|
||||
config = SimpleNamespace(
|
||||
platforms={Platform.TELEGRAM: telegram_cfg},
|
||||
get_home_channel=lambda _platform: None,
|
||||
)
|
||||
with patch("gateway.config.load_gateway_config", return_value=config), \
|
||||
patch("tools.interrupt.is_interrupted", return_value=False):
|
||||
result = json.loads(
|
||||
send_message_tool(
|
||||
{
|
||||
"action": "send",
|
||||
"target": "telegram",
|
||||
"message": "hi",
|
||||
}
|
||||
)
|
||||
)
|
||||
assert "TELEGRAM_HOME_CHANNEL" in result["error"]
|
||||
|
||||
|
||||
class TestSendDiscordThreadId:
|
||||
"""_send_discord uses thread_id when provided."""
|
||||
|
||||
|
||||
@ -44,6 +44,11 @@ _E164_TARGET_RE = re.compile(r"^\s*\+(\d{7,15})\s*$")
|
||||
# an explicit target for the email platform, not fall through to channel-name
|
||||
# resolution which has no way to resolve a raw address.
|
||||
_EMAIL_TARGET_RE = re.compile(r"^\s*[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\s*$")
|
||||
# Most platforms read their home channel from "<PLATFORM>_HOME_CHANNEL", but a
|
||||
# few diverge. Email reads EMAIL_HOME_ADDRESS (see gateway/config.py), so the
|
||||
# generic "<PLATFORM>_HOME_CHANNEL" hint would point users at a variable that is
|
||||
# never read. Map the exceptions so the error guidance is actually actionable.
|
||||
_HOME_CHANNEL_ENV_OVERRIDES = {"email": "EMAIL_HOME_ADDRESS"}
|
||||
_IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".webp", ".gif"}
|
||||
_VIDEO_EXTS = {".mp4", ".mov", ".avi", ".mkv", ".3gp"}
|
||||
_AUDIO_EXTS = {".ogg", ".opus", ".mp3", ".wav", ".m4a", ".flac"}
|
||||
@ -269,10 +274,13 @@ def _handle_send(args):
|
||||
chat_id = home.chat_id
|
||||
used_home_channel = True
|
||||
else:
|
||||
home_env = _HOME_CHANNEL_ENV_OVERRIDES.get(
|
||||
platform_name, f"{platform_name.upper()}_HOME_CHANNEL"
|
||||
)
|
||||
return json.dumps({
|
||||
"error": f"No home channel set for {platform_name} to determine where to send the message. "
|
||||
f"Either specify a channel directly with '{platform_name}:CHANNEL_NAME', "
|
||||
f"or set a home channel via: hermes config set {platform_name.upper()}_HOME_CHANNEL <channel_id>"
|
||||
f"or set a home channel via: hermes config set {home_env} <channel_id>"
|
||||
})
|
||||
|
||||
duplicate_skip = _maybe_skip_cron_duplicate_send(platform_name, chat_id, thread_id)
|
||||
|
||||
Reference in New Issue
Block a user