Refs #892 - Gateway config debt: missing keys and broken fallbacks
Changes:
- Add `_is_network_accessible()` helper to gateway/config.py (avoids circular
import with gateway.platforms.base which imports from gateway.config)
- Add API_SERVER_KEY warning in `_validate_gateway_config`: when the API server
is enabled on a network-accessible address (0.0.0.0, public IP, hostname) but
no key is configured, log a warning at config-load time so operators see the
issue before any adapter initialisation runs
- Add `TestValidateGatewayConfig` in tests/gateway/test_config.py covering:
- idle_minutes <= 0 and None are corrected to 1440 (default)
- at_hour outside 0-23 is corrected to 4 (default)
- Boundary hours 0 and 23 are accepted unchanged
- Empty platform token triggers a warning log
- Disabled platform with empty token produces no warning
- API server on 0.0.0.0 without key logs a warning
- API server on 127.0.0.1 without key is silent (loopback is allowed)
- API server with a key set logs no warning regardless of bind address
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Threads (Telegram forum topics, Discord threads, Slack threads) now default
to shared sessions where all participants see the same conversation. This is
the expected UX for threaded conversations where multiple users @mention the
bot and interact collaboratively.
Changes:
- build_session_key(): when thread_id is present, user_id is no longer
appended to the session key (threads are shared by default)
- New config: thread_sessions_per_user (default: false) — opt-in to restore
per-user isolation in threads if needed
- Sender attribution: messages in shared threads are prefixed with
[sender name] so the agent can tell participants apart
- System prompt: shared threads show 'Multi-user thread' note instead of
a per-turn User line (avoids busting prompt cache)
- Wired through all callers: gateway/run.py, base.py, telegram.py, feishu.py
- Regular group messages (no thread) remain per-user isolated (unchanged)
- DM threads are unaffected (they have their own keying logic)
Closes community request from demontut_ re: thread-based shared sessions.
Home channel env vars (SLACK_HOME_CHANNEL, SIGNAL_HOME_CHANNEL, etc.)
for Slack, Signal, Mattermost, Matrix, Email, and SMS were nested
inside the credential-env blocks, so they were ignored when the
platform was already configured via config.yaml.
Moved the home channel handling outside the credential blocks with a
Platform.X in config.platforms guard, matching the existing pattern
for Telegram and Discord.
Co-authored-by: cutepawss <cutepawss@users.noreply.github.com>
Add unauthorized_dm_behavior config (pair|ignore) with global default
and per-platform override. WhatsApp can silently drop unknown DMs
instead of sending pairing codes.
Adapted config bridging to work with gw_data dict (pre-construction)
rather than config object. Dropped implementation plan document.
Co-authored-by: Frederico Ribeiro <fr@tecompanytea.com>
default group and channel sessions to per-user isolation, allow opting back into shared room sessions via config.yaml, and document Discord gateway routing and session behavior.
Complete the YAML null handling for all three SessionResetPolicy fields.
at_hour and idle_minutes already had null coalescing; mode was still
using data.get('mode', 'both') which returns None when the key exists
with an explicit null value.
Add regression test covering all-null input.
Based on PR #1120 by stablegenius49.
Follow-up on salvaged PR #975.
Bridge quick_commands from config.yaml into load_gateway_config(),
normalize non-dict quick command config at runtime, and add coverage
for GatewayConfig round-trips plus config.yaml bridging. This makes the
GatewayConfig quick-command fix complete for the real user-facing config
path implicated by issue #973.