Skip to content

feat(seer-slack): Refresh Slack thread status to prevent 2-min auto-clear#112679

Draft
alexsohn1126 wants to merge 15 commits intomasterfrom
alexsohn/refresh-thinking-status-seer-slack-mentions
Draft

feat(seer-slack): Refresh Slack thread status to prevent 2-min auto-clear#112679
alexsohn1126 wants to merge 15 commits intomasterfrom
alexsohn/refresh-thinking-status-seer-slack-mentions

Conversation

@alexsohn1126
Copy link
Copy Markdown
Member

@alexsohn1126 alexsohn1126 commented Apr 10, 2026

Motivation

According to the Slack's set thread status docs, the status only lasts for 2 minutes. For those tasks that take longer than 2 minutes, the status clears, and the user is left confused as of the status of the agent call.

Solution

We will run a delayed task that runs 90 seconds after the initial setStatus, and will refresh the status as long as the SeerOperatorExplorerCache is alive. Then it will schedule another task 90 seconds out until the refresh limit (6 times) is reached.

That also means now we will manually delete the cache in the completion hook when seer agent has completed. Slack's API document states that the status will be automatically cleared once the reply has been received, so we won't need to clear the status manually.

Perhaps there's a more elegant solution to this. Open for ideas

Completes ISWF-2426

leeandher and others added 8 commits April 10, 2026 10:02
Add the assistant:write scope to the Slack integration to enable
the bot to act as a Slack Agent, supporting DM-based agent interfaces.

Refs ISWF-2388
Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
Extract shared org-resolution logic into _resolve_seer_organization helper
and merge on_app_mention/on_dm into a single _handle_seer_mention method.
Replace three identical halt reason enums with unified SeerSlackHaltReason.
Extract duplicated loading messages list into a module-level constant.

Refs ISWF-2388
Co-Authored-By: Claude Opus 4.6 <noreply@example.com>
…nges

Update tests to match the refactored _resolve_seer_organization which
now iterates org integrations and uses SlackExplorerEntrypoint.has_access
instead of checking a single feature flag. Align halt reasons with the
consolidated enum values (NO_VALID_INTEGRATION, NO_VALID_ORGANIZATION)
and update the has_access test for the seer-slack-explorer flag rename.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address PR review feedback:
- Change SLACK_PROVIDERS from set to list to match the RPC method's
  expected `list[str]` parameter type, preventing serialization errors
- Check org status before calling get_installation to avoid unnecessary
  queries for inactive orgs
- Verify the requesting Slack user belongs to the resolved org when
  their identity is linked, preventing cross-org data access when
  multiple orgs share a Slack workspace
- Fix inaccurate comments about DM fallback behavior

Refs ISWF-2388
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…uests

Move identity verification to the start of org resolution so unlinked
users receive an ephemeral prompt with a link button instead of silently
failing downstream. Introduce SeerResolutionResult TypedDict to replace
the tuple-or-None return pattern, add a static ephemeral message helper
on SlackIntegration, and simplify DM dispatch by routing assistant-scoped
integrations through the mention handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lear

Slack's assistant_threads.setStatus auto-clears after 2 minutes of no
message. When Seer processing takes longer, the "Thinking..." indicator
silently disappears while the user is still waiting for a response.

Add a self-chaining Celery task that re-sends the thread status every
90 seconds. After trigger_explorer() returns a run_id, the first refresh
is scheduled. Each refresh checks the SeerOperatorExplorerCache — if the
cache entry still exists, the run is in progress and the status is
refreshed. When the completion hook fires, it deletes the cache before
sending the reply, so subsequent refreshes become no-ops.

The refresh chain is capped at 6 iterations (~11 min total coverage).
The completion hook now also deletes the explorer cache entry after use
so the refresh task can detect completion.
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 10, 2026
Narrow handler signatures from SlackDMRequest to SlackEventRequest for
better type safety. Extract channel_id, user_id, and thread_ts
properties on SlackEventRequest to handle assistant_thread_started event
structure differences in one place. Rename on_app_mention to on_prompt
and is_assistant to has_assistant_scope for clarity. Add contextual
messaging to the identity link prompt based on event type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@linear-code
Copy link
Copy Markdown

linear-code bot commented Apr 10, 2026

leeandher and others added 6 commits April 10, 2026 13:07
Remove the ts fallback from SlackEventRequest.thread_ts so top-level
messages correctly yield None instead of collapsing into the message ts.
Add missing return type annotations to has_assistant_scope and
is_assistant_thread_event. Move variable extraction before org
resolution in _handle_seer_prompt for earlier lifecycle context.
…rface-for-seer-explorer' into alexsohn/refresh-thinking-status-seer-slack-mentions
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

Backend Test Failures

Failures on 180e9f5 in this run:

tests/sentry/integrations/slack/webhooks/events/test_message_im.py::MessageIMDmAgentTest::test_dm_dispatches_tasklog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/integrations/slack/webhooks/events/test_message_im.py:230: in test_dm_dispatches_task
    assert kwargs["thread_ts"] is None
E   AssertionError: assert '' is None
tests/sentry/integrations/slack/webhooks/events/test_app_mention.py::AppMentionEventTest::test_app_mention_non_threaded_dispatches_tasklog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/integrations/slack/webhooks/events/test_app_mention.py:71: in test_app_mention_non_threaded_dispatches_task
    assert kwargs["thread_ts"] is None
E   AssertionError: assert '' is None

Base automatically changed from leanderrodrigues/iswf-2388-explore-slack-dms-agent-interface-for-seer-explorer to master April 10, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants