fix(slack): rehydrate thread context after restart - #33215
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the restart rehydration case and covering retry and session-scope variants.
Problems
- The PR edits
gateway/platforms/slack.py, but commit5600105478ffde29d7566b45421b100eaa29c4efmigrated the live adapter toplugins/platforms/slack/adapter.py. Current main still has the active-session guard that suppresses hydration atplugins/platforms/slack/adapter.py:2888-2900, so this needs a targeted port rather than applying the old-path diff.
Suggested changes
- Reapply the marker-based one-shot hydration logic in
plugins/platforms/slack/adapter.pyand relocate the regression tests to the current test layout. Preserve the current routing changes aroundplugins/platforms/slack/adapter.py:2819-2868while doing so.
Automated hermes-sweeper review.
| # a restarted gateway can treat an incomplete/sparse session as | ||
| # authoritative and only inject the thread parent quote. Fetching | ||
| # once per process/thread rehydrates Slack-side context without | ||
| # prepending the full thread on every reply. Entries are added only |
There was a problem hiding this comment.
Current main no longer loads this adapter path: commit 5600105478ffde29d7566b45421b100eaa29c4ef moved it to plugins/platforms/slack/adapter.py. Please port this state and the call-site change to that live plugin adapter.
764f70c to
f08cfb5
Compare
|
Addressed the review in
Verification: focused regressions 8 passed; all |
Persistent sessions survive gateway restarts, but thread replies posted while the gateway was DOWN never reached the session — and the adapter had no way to notice, so the conversation silently resumed with a hole in it. On the first ordinary reply per thread after a restart (tracked by a fresh-process _thread_rehydration_checked set), fetch the thread delta past the persisted per-session watermark and inject any missed messages as part of the new turn via channel_context. Exactly-once per thread per process; when the watermark is empty (pre-feature sessions) the check is a no-op. Steady-state replies keep advancing the watermark so rehydration never re-injects messages the session already carries as ordinary turns. Prior history is never rewritten (prompt caching safe). Builds on the persisted watermark introduced for #23918. Salvaged from #33215 by @vexclawx31, reworked from a repeated full-thread injection guard into a watermark-delta injection so rehydration adds only what the session actually missed.
Persistent sessions survive gateway restarts, but thread replies posted while the gateway was DOWN never reached the session — and the adapter had no way to notice, so the conversation silently resumed with a hole in it. On the first ordinary reply per thread after a restart (tracked by a fresh-process _thread_rehydration_checked set), fetch the thread delta past the persisted per-session watermark and inject any missed messages as part of the new turn via channel_context. Exactly-once per thread per process; when the watermark is empty (pre-feature sessions) the check is a no-op. Steady-state replies keep advancing the watermark so rehydration never re-injects messages the session already carries as ordinary turns. Prior history is never rewritten (prompt caching safe). Builds on the persisted watermark introduced for #23918. Salvaged from #33215 by @vexclawx31, reworked from a repeated full-thread injection guard into a watermark-delta injection so rehydration adds only what the session actually missed.
|
Merged via #69320 — your commit was cherry-picked onto current main with your authorship preserved in git history: your restart rehydration landed via the watermark delta mechanism with your authorship. Thanks for the contribution! |
Persistent sessions survive gateway restarts, but thread replies posted while the gateway was DOWN never reached the session — and the adapter had no way to notice, so the conversation silently resumed with a hole in it. On the first ordinary reply per thread after a restart (tracked by a fresh-process _thread_rehydration_checked set), fetch the thread delta past the persisted per-session watermark and inject any missed messages as part of the new turn via channel_context. Exactly-once per thread per process; when the watermark is empty (pre-feature sessions) the check is a no-op. Steady-state replies keep advancing the watermark so rehydration never re-injects messages the session already carries as ordinary turns. Prior history is never rewritten (prompt caching safe). Builds on the persisted watermark introduced for NousResearch#23918. Salvaged from NousResearch#33215 by @vexclawx31, reworked from a repeated full-thread injection guard into a watermark-delta injection so rehydration adds only what the session actually missed.
…lvage LevSky22 (NousResearch#66069), vexclawx31 (NousResearch#33215), knoal (NousResearch#64067), kaiyisg (NousResearch#24848).
Summary
plugins/platforms/slack/adapter.pyon currentmainthread_sessions_per_userisolationTest Plan
.venv/bin/python -m pytest tests/gateway/test_slack.py::TestSlackThreadContextRehydration tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_api_empty_thread_is_not_cached_and_retries tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_force_refresh_bypasses_nonempty_context_cache -q -o 'addopts='— 8 passed.venv/bin/python -m pytest tests/gateway/test_slack*.py -q -o 'addopts='— 449 passed (52 existing runtime warnings).venv/bin/ruff check plugins/platforms/slack/adapter.py tests/gateway/test_slack.py tests/gateway/test_slack_approval_buttons.py— passedgit diff --check— passedNotes
This branch was rebuilt on current upstream
main; the obsoletegateway/platforms/slack.pychanges are no longer present.