Bug Description
SlackAdapter._has_active_session_for_thread() builds the session key manually and always appends user_id to it. However, build_session_key() in gateway/session.py intentionally omits user_id for threads when thread_sessions_per_user=False (the default), because threads are designed to be shared sessions across all participants.
This key mismatch means the method never finds an existing session, so all thread replies without an explicit @mention are silently ignored — even when the bot has an active session in that thread.
Steps to Reproduce
- In a Slack channel, mention the bot (e.g.
@hermes_agent hello) — bot responds in a thread
- Reply in that thread without mentioning the bot
- Expected: bot processes the reply (active session exists)
- Actual: bot ignores the reply
Root Cause
In gateway/platforms/slack.py, _has_active_session_for_thread() (around line 979) manually constructs the session key:
key_parts = ["agent:main", "slack", "group", channel_id, thread_ts]
group_sessions_per_user = True # Default
if group_sessions_per_user and user_id:
key_parts.append(str(user_id)) # Always appended!
But build_session_key() in gateway/session.py has this logic:
isolate_user = group_sessions_per_user
if source.thread_id and not thread_sessions_per_user:
isolate_user = False # user_id NOT appended for threads
So the actual session is stored under a key without user_id, but the lookup searches for a key with user_id → never matches.
Proposed Fix
Replace the manual key construction with a call to build_session_key() — single source of truth:
try:
- from gateway.session import SessionSource
+ from gateway.session import SessionSource, build_session_key
from gateway.config import Platform
source = SessionSource(
platform=Platform.SLACK,
chat_id=channel_id,
chat_type="group",
user_id=user_id,
thread_id=thread_ts,
)
- key_parts = ["agent:main", "slack", "group", channel_id, thread_ts]
-
- group_sessions_per_user = getattr(
- session_store, "config", {}
- )
- if hasattr(group_sessions_per_user, "group_sessions_per_user"):
- group_sessions_per_user = group_sessions_per_user.group_sessions_per_user
- else:
- group_sessions_per_user = True
-
- if group_sessions_per_user and user_id:
- key_parts.append(str(user_id))
-
- session_key = ":".join(key_parts)
+ store_config = getattr(session_store, "config", None)
+ session_key = build_session_key(
+ source,
+ group_sessions_per_user=getattr(store_config, "group_sessions_per_user", True),
+ thread_sessions_per_user=getattr(store_config, "thread_sessions_per_user", False),
+ )
Tested locally — thread replies without @mention now work correctly when the bot has an active session.
Bug Description
SlackAdapter._has_active_session_for_thread()builds the session key manually and always appendsuser_idto it. However,build_session_key()ingateway/session.pyintentionally omitsuser_idfor threads whenthread_sessions_per_user=False(the default), because threads are designed to be shared sessions across all participants.This key mismatch means the method never finds an existing session, so all thread replies without an explicit @mention are silently ignored — even when the bot has an active session in that thread.
Steps to Reproduce
@hermes_agent hello) — bot responds in a threadRoot Cause
In
gateway/platforms/slack.py,_has_active_session_for_thread()(around line 979) manually constructs the session key:But
build_session_key()ingateway/session.pyhas this logic:So the actual session is stored under a key without
user_id, but the lookup searches for a key withuser_id→ never matches.Proposed Fix
Replace the manual key construction with a call to
build_session_key()— single source of truth:Tested locally — thread replies without @mention now work correctly when the bot has an active session.