fix: Signal adapter parity pass — integration gaps, clawdbot features, env var simplification

Integration gaps fixed (7 files missing Signal):
- cron/scheduler.py: Signal in platform_map (cron delivery was broken)
- agent/prompt_builder.py: PLATFORM_HINTS for Signal (agent knows it's on Signal)
- toolsets.py: hermes-signal toolset + added to hermes-gateway composite
- hermes_cli/status.py: Signal + Slack in platform status display
- tools/send_message_tool.py: Signal example in target description
- tools/cronjob_tools.py: Signal in delivery option docs + schema
- gateway/channel_directory.py: Signal in session-based channel discovery

Clawdbot parity features added to signal.py:
- Self-message filtering: prevents reply loops by checking sender != account
- SyncMessage filtering: ignores sync envelopes (sent transcripts, read receipts)
- Edit message support: reads dataMessage from editMessage envelope
- Mention rendering: replaces \uFFFC placeholders with @identifier text
- Jitter in SSE reconnection backoff (20% randomization, prevents thundering herd)

Env var simplification (7 → 4):
- Removed SIGNAL_DM_POLICY (DM auth follows standard platform pattern via
  SIGNAL_ALLOWED_USERS + DM pairing, same as Telegram/Discord)
- Removed SIGNAL_GROUP_POLICY (derived from SIGNAL_GROUP_ALLOWED_USERS:
  not set = disabled, set with IDs = allowlist, set with * = open)
- Removed SIGNAL_DEBUG (was setting root logger, removed entirely)
- Remaining: SIGNAL_HTTP_URL, SIGNAL_ACCOUNT (required),
  SIGNAL_ALLOWED_USERS, SIGNAL_GROUP_ALLOWED_USERS (optional)

Updated all docs (website, AGENTS.md, signal.md) to match.
This commit is contained in:
teknium1 2026-03-08 21:00:21 -07:00
parent 0c4cff352a
commit b7d6eae64c
14 changed files with 645 additions and 621 deletions

View file

@ -757,42 +757,25 @@ def _setup_signal():
save_env_value("SIGNAL_ALLOWED_USERS", allowed)
# DM policy
# Group messaging
print()
policies = ["pairing (default — new users get a pairing code to approve)",
"allowlist (only explicitly listed users)",
"open (anyone can message)"]
dm_choice = prompt_choice(" DM access policy:", policies, 0)
dm_policy = ["pairing", "allowlist", "open"][dm_choice]
save_env_value("SIGNAL_DM_POLICY", dm_policy)
# Group policy
print()
group_policies = ["disabled (default — ignore group messages)",
"allowlist (only specific groups)",
"open (respond in any group the bot is in)"]
group_choice = prompt_choice(" Group message policy:", group_policies, 0)
group_policy = ["disabled", "allowlist", "open"][group_choice]
save_env_value("SIGNAL_GROUP_POLICY", group_policy)
if group_policy == "allowlist":
if prompt_yes_no(" Enable group messaging? (disabled by default for security)", False):
print()
print_info(" Enter group IDs to allow (comma-separated).")
print_info(" Enter group IDs to allow, or * for all groups.")
existing_groups = get_env_value("SIGNAL_GROUP_ALLOWED_USERS") or ""
try:
groups = input(f" Group IDs [{existing_groups}]: ").strip() or existing_groups
groups = input(f" Group IDs [{existing_groups or '*'}]: ").strip() or existing_groups or "*"
except (EOFError, KeyboardInterrupt):
print("\n Setup cancelled.")
return
if groups:
save_env_value("SIGNAL_GROUP_ALLOWED_USERS", groups)
save_env_value("SIGNAL_GROUP_ALLOWED_USERS", groups)
print()
print_success("Signal configured!")
print_info(f" URL: {url}")
print_info(f" Account: {account}")
print_info(f" DM policy: {dm_policy}")
print_info(f" Group policy: {group_policy}")
print_info(f" DM auth: via SIGNAL_ALLOWED_USERS + DM pairing")
print_info(f" Groups: {'enabled' if get_env_value('SIGNAL_GROUP_ALLOWED_USERS') else 'disabled'}")
def gateway_setup():

View file

@ -206,6 +206,8 @@ def show_status(args):
"Telegram": ("TELEGRAM_BOT_TOKEN", "TELEGRAM_HOME_CHANNEL"),
"Discord": ("DISCORD_BOT_TOKEN", "DISCORD_HOME_CHANNEL"),
"WhatsApp": ("WHATSAPP_ENABLED", None),
"Signal": ("SIGNAL_HTTP_URL", "SIGNAL_HOME_CHANNEL"),
"Slack": ("SLACK_BOT_TOKEN", None),
}
for name, (token_var, home_var) in platforms.items():