fix(slack): include bot's own prior replies in cold-start thread context - #38936
Closed
temalo wants to merge 1 commit into
Closed
fix(slack): include bot's own prior replies in cold-start thread context#38936temalo wants to merge 1 commit into
temalo wants to merge 1 commit into
Conversation
_fetch_thread_context unconditionally dropped self-bot child replies before injection. The guard makes sense on the active-session path (where the session history already carries those replies and re-injecting them would be circular), but this method is only called from the cold-start branch — the call site is wrapped in 'if not _has_active_session_for_thread(...)'. On that path, dropping the bot's prior replies leaves the agent with user messages only and no way to reconstruct what it (or a sibling cron session that posted the parent) already said. Keep self-bot child replies on the cold-start path and label them with an explicit [assistant] prefix so the agent can distinguish its own prior turns from user messages and from third-party bot posts. Per-workspace self-bot detection (self._team_bot_user_ids per msg_team) is preserved verbatim. User-name resolution is skipped for self-bot turns — the [assistant] label already communicates authorship. Test coverage in tests/gateway/test_slack_approval_buttons.py: - new: test_includes_self_bot_replies_as_assistant_on_cold_start - updated: test_fetch_thread_context_includes_self_bot_replies_with_assistant_label - updated: test_fetch_thread_context_multi_workspace (per-workspace filter still applied, just no longer drops the self reply) - regression guards left intact: parent labelling, bot-mention stripping, current_ts exclusion, empty/error paths Fixes NousResearch#38861
Contributor
|
Thanks for identifying a live cold-start context gap. Current main still skips self-bot child replies at Problems
Suggested changes
Automated hermes-sweeper review. |
teknium1
pushed a commit
that referenced
this pull request
Jul 22, 2026
_fetch_thread_context unconditionally filtered out the bot's own prior replies, so cold-start sessions (bot posts a thread root, user replies later, no active session) lost every assistant turn and the agent could not reconstruct the prior conversation. The circular-context concern the filter guarded against does not apply here: the call site is gated by _has_active_session_for_thread, so this method only runs when there is no session history to duplicate. Self-bot replies are now kept and labelled with an explicit [assistant] prefix (skipping user-name resolution — the label already communicates authorship). Third-party bot posts and the bot-authored thread parent keep their existing treatment. Fixes #38861. Salvaged from #38936 by @temalo, rebased from the pre-plugin gateway/platforms/slack.py layout onto plugins/platforms/slack/adapter.py (preserving the [unverified] trust-tag handling added on main since).
teknium1
pushed a commit
that referenced
this pull request
Jul 22, 2026
_fetch_thread_context unconditionally filtered out the bot's own prior replies, so cold-start sessions (bot posts a thread root, user replies later, no active session) lost every assistant turn and the agent could not reconstruct the prior conversation. The circular-context concern the filter guarded against does not apply here: the call site is gated by _has_active_session_for_thread, so this method only runs when there is no session history to duplicate. Self-bot replies are now kept and labelled with an explicit [assistant] prefix (skipping user-name resolution — the label already communicates authorship). Third-party bot posts and the bot-authored thread parent keep their existing treatment. Fixes #38861. Salvaged from #38936 by @temalo, rebased from the pre-plugin gateway/platforms/slack.py layout onto plugins/platforms/slack/adapter.py (preserving the [unverified] trust-tag handling added on main since).
Contributor
|
Merged via #69320 — your commit was cherry-picked onto current main with your authorship preserved in git history: your cold-start bot-reply inclusion was reapplied onto the plugin adapter with your authorship, preserving main's [unverified] trust-tag logic. Thanks for the contribution! |
randlee
pushed a commit
to randlee/hermes-agent
that referenced
this pull request
Aug 11, 2026
_fetch_thread_context unconditionally filtered out the bot's own prior replies, so cold-start sessions (bot posts a thread root, user replies later, no active session) lost every assistant turn and the agent could not reconstruct the prior conversation. The circular-context concern the filter guarded against does not apply here: the call site is gated by _has_active_session_for_thread, so this method only runs when there is no session history to duplicate. Self-bot replies are now kept and labelled with an explicit [assistant] prefix (skipping user-name resolution — the label already communicates authorship). Third-party bot posts and the bot-authored thread parent keep their existing treatment. Fixes NousResearch#38861. Salvaged from NousResearch#38936 by @temalo, rebased from the pre-plugin gateway/platforms/slack.py layout onto plugins/platforms/slack/adapter.py (preserving the [unverified] trust-tag handling added on main since).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
In
_fetch_thread_context(gateway/platforms/slack.py), the bot's own priorreplies in a thread were unconditionally filtered out before injection. The
guard was sound for the active-session path (where the session history
already carries those replies and re-injecting them would be circular), but
_fetch_thread_contextis only called when there is no active session forthe thread — the call site at line 2361 is wrapped in
if not self._has_active_session_for_thread(...). On that cold-start path,dropping the bot's prior replies leaves the agent with only user messages and
no way to reconstruct what it (or a sibling cron session that posted the
thread parent) already said.
Concrete failure mode: a cron job posts a thread parent → a user replies in
the thread → a different agent session warms up → the agent sees user turns
only, has to guess at the prior conversation, and often re-asks for
information the bot already provided.
Fixes #38861.
What
gateway/platforms/slack.py—_fetch_thread_contextnow keeps self-botchild replies and labels them with an explicit
[assistant]prefix instead ofcontinue-ing past them. The per-workspace bot-id resolution(
self._team_bot_user_ids.get(msg_team) or self._bot_user_id) is preservedverbatim, so the existing multi-workspace correctness (only our bot in
this workspace is treated as self) still holds.
Detection logic moves into a single boolean (
is_self_bot_reply); the prefixladder becomes
[thread parent] | [assistant] | ""; user-name resolution isskipped for self-bot turns (the
[assistant]label already communicatesauthorship and the resolved name would just be our own bot handle).
Behaviour change footprint
[assistant][thread parent](unchanged)[thread parent](unchanged)_has_active_session_for_threadtrue)self._team_bot_user_idspermsg_team(unchanged)self._team_bot_user_idspermsg_team(unchanged)The active-session circular-context concern that originally motivated the
filter does not apply here — that path simply never reaches this method.
Test coverage
tests/gateway/test_slack_approval_buttons.py:test_includes_self_bot_replies_as_assistant_on_cold_start(new behaviour)[assistant]prefix, third-party bot kept,[assistant]label does not leak to user linestest_fetch_thread_context_includes_self_bot_replies_with_assistant_label(renamed/updated from_excludes_self_bot_replies)[thread parent], self-bot child kept with[assistant], user replies kepttest_fetch_thread_context_multi_workspace(updated)[assistant]rather than dropped; T1's bot id appearing in a T2 message is treated as third-party and kept by its display nametest_fetches_and_formats_context(unchanged, regression guard)test_fetch_thread_context_includes_bot_parent(unchanged, regression guard)[thread parent]test_fetch_thread_context_current_ts_excluded(unchanged, regression guard)test_empty_thread,test_api_failure_returns_empty(unchanged)Verification on this branch:
The 38 failures are all pre-existing on
upstream/main(telegram/whatsappadapters, status-command onboarding) — diffed against a pristine
upstream/mainbaseline run, the set of failures is bit-for-bit identical.No new failures introduced by this change.
Out of scope
_thread_context_cachereuse during a livesession) — not touched; that path was already correct.
_fetch_thread_parent_text— same cache, but only ever returns the parenttext; the self-bot filter never applied there.
out of scope; the issue and its repro are Slack-specific.
[assistant]lines as actual assistant-role messages in theagent's message list. Cold-start context is injected as a single user-role
preamble today; promoting individual lines back into typed turns would be
a broader gateway refactor and a separate change.