Skip to content

feat(slack): per-thread session isolation for DM auto-threading#26849

Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom
calder-sandy:sandy/dm-thread-sessions
Mar 1, 2026
Merged

feat(slack): per-thread session isolation for DM auto-threading#26849
Takhoffman merged 2 commits intoopenclaw:mainfrom
calder-sandy:sandy/dm-thread-sessions

Conversation

@calder-sandy
Copy link
Contributor

@calder-sandy calder-sandy commented Feb 25, 2026

Summary

When replyToMode="all" is configured, every top-level Slack DM starts a new thread. However, only subsequent replies in that thread received an isolated session (:thread:<threadTs> suffix). The initial message still fell back to the base DM session, mixing context across unrelated conversations.

This PR fixes that by using the message's own ts as the thread ID for session key resolution when replyToMode="all" and the message is not already a thread reply.

Before

  1. User sends "fix PR feat: Add GitHub authentication helper commands #259" → routes to agent:main:slack:direct:U123 (base DM session)
  2. Bot replies in a thread (via replyToMode=all)
  3. User replies in that thread → routes to agent:main:slack:direct:U123:thread:1234.000
  4. User sends new top-level "check Dagster" → routes to agent:main:slack:direct:U123 (same session as step 1) ❌

After

  1. User sends "fix PR feat: Add GitHub authentication helper commands #259" → routes to agent:main:slack:direct:U123:thread:1234.000
  2. Bot replies in that thread
  3. User replies in that thread → routes to agent:main:slack:direct:U123:thread:1234.000
  4. User sends new top-level "check Dagster" → routes to agent:main:slack:direct:U123:thread:1235.000 ✅ (isolated)

Changes

  • src/slack/monitor/message-handler/prepare.ts: When replyToMode="all" and the message is not a thread reply, use messageTs as threadId in resolveThreadSessionKeys so the initial message gets its own thread session.
  • src/slack/monitor/message-handler/prepare.test.ts: Added test verifying thread session creation for top-level DMs with replyToMode="all".

Configuration

To enable per-thread DM sessions, set:

{
  channels: {
    slack: {
      replyToMode: "all",  // or use replyToModeByChatType.direct: "all"
    }
  }
}

Test plan

  • Existing threading tests pass (21/21)
  • Existing prepare tests pass (17/17)
  • New test: top-level DM with replyToMode=all creates thread session key

Greptile Summary

This PR fixes session isolation for initial top-level messages when replyToMode="all" is configured for Slack. Previously, only subsequent replies in auto-created threads received an isolated session key (with :thread:<threadTs> suffix), while the initial message fell back to the base DM/channel session — causing context bleed across unrelated conversations.

The fix introduces an autoThreadId variable in prepare.ts that uses the message's own ts as the thread ID for session key resolution when replyToMode="all" and the message is not already a thread reply. This aligns session key behavior with the existing messageThreadId logic in resolveSlackThreadContext (which already set messageThreadId to messageTs for top-level messages with replyToMode="all").

  • The change is narrowly scoped: autoThreadId only activates when replyToMode === "all", leaving "off" and "first" modes unaffected
  • parentSessionKey is correctly updated to also apply when autoThreadId is set, maintaining consistency with threadInheritParent behavior
  • A new test verifies the session key and MessageThreadId for top-level DMs with replyToMode="all"

Confidence Score: 5/5

  • This PR is safe to merge — it's a targeted bug fix with clear logic and adequate test coverage.
  • The change is small, well-scoped, and logically sound. It mirrors existing patterns in resolveSlackThreadContext (which already sets messageThreadId for replyToMode="all" top-level messages) and extends the same logic to session key resolution. The guard conditions ensure it only activates for replyToMode="all", leaving other modes unaffected. The new test adequately covers the fix. No security, performance, or regression concerns.
  • No files require special attention.

Last reviewed commit: 40e0bee

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

@openclaw-barnacle openclaw-barnacle bot added channel: slack Channel integration: slack size: XS labels Feb 25, 2026
calder-sandy and others added 2 commits March 1, 2026 11:04
When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.
@Takhoffman Takhoffman force-pushed the sandy/dm-thread-sessions branch from 40e0bee to e24d998 Compare March 1, 2026 17:24
@Takhoffman Takhoffman merged commit 93ac2b4 into openclaw:main Mar 1, 2026
3 checks passed
@Takhoffman
Copy link
Contributor

Merged via salvage path.

Merge commit: 93ac2b4
Head commit pinned: e24d998

What changed before merge:

  • rebased onto latest main (clean)
  • fixed mode-check regression to use per-chat resolved replyToMode (not monitor startup default) when deriving auto-thread session IDs
  • added missing changelog entry for DM auto-thread session isolation behavior

Verification run on the rebased branch:

  • CI=true pnpm install --frozen-lockfile
  • pnpm build
  • pnpm check
  • pnpm test:macmini

All checks passed.

zooqueen added a commit to hanzoai/bot that referenced this pull request Mar 1, 2026
ansh pushed a commit to vibecode/openclaw that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
safzanpirani pushed a commit to safzanpirani/clawdbot that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
amitmiran137 pushed a commit to amitmiran137/openclaw that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
hanqizheng pushed a commit to hanqizheng/openclaw that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
sachinkundu pushed a commit to sachinkundu/openclaw that referenced this pull request Mar 6, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…claw#26849)

* feat(slack): create thread sessions for auto-threaded DM messages

When replyToMode="all", every top-level message starts a new Slack thread.
Previously, only subsequent replies in that thread got an isolated session
(via 🧵<threadTs> suffix). The initial message fell back to the base
DM session, mixing context across unrelated conversations.

Now, when replyToMode="all" and a message is not already a thread reply,
the message's own ts is used as the threadId for session key resolution.
This gives the initial message AND all subsequent thread replies the same
isolated session.

This enables per-thread session isolation for Slack DMs — each new message
starts its own thread and session, keeping conversations separate.

* Slack: fix auto-thread session key mode check and add changelog

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen added a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: slack Channel integration: slack size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants