## Problem
When multiple channels (WhatsApp, iMessage, Telegram, etc.) are active,
responses intended for one channel could leak to another channel if
messages arrived simultaneously. This created serious privacy concerns.
**Root Cause:**
All channels were updating the SAME main session key with their delivery
context (channel, to, accountId). When messages arrived concurrently:
1. WhatsApp message arrives → updates session['agent:main:main'].lastChannel = 'whatsapp'
2. Agent starts processing (takes time)
3. iMessage message arrives → OVERWRITES session['agent:main:main'].lastChannel = 'imessage'
4. WhatsApp response delivers → reads session lastChannel = 'imessage'
5. Response goes to wrong channel!
## Solution
Changed all channel monitors to use the channel-specific session key
(route.sessionKey) instead of the shared main session key
(route.mainSessionKey) when updating delivery context.
Now each channel updates its own isolated session:
- WhatsApp: session['agent:main:whatsapp:dm:+1234']
- iMessage: session['agent:main:imessage:dm:alice']
- Telegram: session['agent:main:telegram:dm:12345']
This prevents cross-channel state clobbering.
## Changes
- src/discord/monitor/message-handler.process.ts
- src/imessage/monitor/monitor-provider.ts
- src/line/bot-message-context.ts
- src/signal/monitor/event-handler.ts
- src/slack/monitor/message-handler/dispatch.ts
- src/slack/monitor/message-handler/prepare.ts
- src/telegram/bot-message-context.ts
- src/web/auto-reply/monitor/process-message.ts
All changed from:
sessionKey: route.mainSessionKey
To:
sessionKey: route.sessionKey
## Testing
Manual testing needed:
1. Configure 2+ channels (e.g., WhatsApp + iMessage)
2. Send message to channel A
3. Immediately send message to channel B (within 100ms)
4. Verify responses go to correct channels
Fixes#4530
When replying to a Slack thread, files attached to the root message were
not being fetched. The existing `resolveSlackThreadStarter()` fetched the
root message text via `conversations.replies` but ignored the `files[]`
array in the response.
Changes:
- Add `files` to `SlackThreadStarter` type and extract from API response
- Download thread starter files when the reply message has no attachments
- Add verbose log for thread starter file hydration
Fixes issue where asking about a PDF in a thread reply would fail because
the model never received the file content from the root message.
Fixes two bugs in Slack tool notification delivery:
1. Tool notifications ignored verbose=false - normalized verbose values so
boolean false/'false' are properly treated as 'off'
2. Thread context lost - Slack outbound adapter now falls back to threadId
when replyToId is missing, and MessageThreadId is set for thread replies
Closes#1333
The `channels.slack.requireMention` setting was defined in the schema
but never passed to `resolveSlackChannelConfig()`, which always
defaulted to `true`. This meant setting `requireMention: false` at the
top level had no effect—channels still required mentions.
Pass `slackCfg.requireMention` as `defaultRequireMention` to the
resolver and use it as the fallback instead of hardcoded `true`.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>