Skip to content

feat(slack): Reply to @-mentions when Seer runs out of credits - #130440

Open
alexsohn1126 wants to merge 7 commits into
alexsohn/cw-2325-slack-out-of-credits-repliesfrom
alexsohn/cw-2325-slack-out-of-credits-mention-replies
Open

alexsohn1126 wants to merge 7 commits into
alexsohn/cw-2325-slack-out-of-credits-repliesfrom
alexsohn/cw-2325-slack-out-of-credits-mention-replies

Conversation

@alexsohn1126

@alexsohn1126 alexsohn1126 commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

This PR replies to the thread when @sentry is mentioned and the organization does not have enough seer credits for the operation.

There are multiple ways that a Seer Agent will fail.

  • When mentioned, the org does not have any seer credits
  • When mentioned, the org has seer credits, but during the seer call, seer returns with out-of-credit error
  • When mentioned, the org has seer credits, but during the PR generation, the PR generation fails due to no seer credit

In all cases, we send a message like this:

image

And for PR creation, this would be shown (along with the standard message we send)

image

Fixes CW-2325

@linear-code

linear-code Bot commented Nov 9, 2026

Copy link
Copy Markdown

CW-2325

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Nov 9, 2026
@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch from 40899d5 to fa1ae81 Compare November 9, 2026 15:54
@sentry

sentry Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Sentry Snapshot Testing

Name Added Removed Changed Renamed Unchanged Skipped Status
sentry-frontend
sentry-frontend
0 0 0 0 824 0 ✅ Unchanged

⚙️ sentry-frontend Snapshot Settings

@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch 6 times, most recently from c62ef58 to 93db726 Compare November 9, 2026 20:23
@alexsohn1126
alexsohn1126 removed this pull request from stack #130441 November 9, 2026 20:24
@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch from 93db726 to c90d978 Compare November 9, 2026 20:29
@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch 7 times, most recently from e18a83b to 7bc8ef8 Compare November 10, 2026 21:04
@alexsohn1126

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch 2 times, most recently from 3d425d4 to 27944c5 Compare November 12, 2026 15:26
@alexsohn1126

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

title: str | None = None
description: str | None = None
integration_id: str | None = None
idempotency_key: str | None = Field(default=None, exclude=True)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this allows us to give each PR push attempt its own unique key, so we can send "out of credits" message again if the PR push fails, and user @ mentions again to do a PR push.

@alexsohn1126

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@alexsohn1126
alexsohn1126 marked this pull request as ready for review November 12, 2026 17:51
@alexsohn1126
alexsohn1126 requested a review from a team as a code owner November 12, 2026 17:51
@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch from 540ee18 to 6360888 Compare November 12, 2026 17:59
key
for pr in _get_repo_pr_states(state)
if _is_pr_out_of_credits(pr)
and (key := f"pr_out_of_credits:{pr.repo_name}:{pr.idempotency_key}") not in replies

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Reply-cache docstring doesn't list the new out-of-credits keys

The docstring on SlackSeerAgentReplyCache in cache.py (lines 68–72, outside this diff) lists every reply key: the answer's block id, approval:<input id>, approval_dm:<input id>, and error. It describes itself as the only record of what was posted. This PR adds out_of_credits:<turn's first block id> and pr_out_of_credits:<repo>:<push key>. Add them to that list so the next person changing dedupe logic sees every key kind in one place.

Written by an AI agent and included in this review by its author.

_send_out_of_credits_message(
entrypoint=entrypoint,
organization=organization,
thread_ts=thread_ts or ts,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is true or not

🤖 Top-level @-mentions likely never see the ephemeral out-of-credits reply

For a top-level @-mention, thread_ts is None. The ephemeral therefore goes out with thread_ts=ts, into a thread on the user's own message that has no replies yet. Slack's chat.postEphemeral docs say ephemeral messages in threads only show if the thread is already active. This path returns before anything public is posted, so that thread never becomes active. The person who mentioned @sentry would see the "is thinking..." status clear and nothing else. That's case 1 in the description, and probably the most common one.

The halt paths a few lines up already handle this with thread_ts if thread_ts else "" and the comment "In a thread, show the prompt in the thread; top-level, show in the channel". Doing the same here posts the notice in the channel for top-level mentions:

Suggested change
thread_ts=thread_ts or ts,
thread_ts=thread_ts if thread_ts else "",

(_send_out_of_credits_message's docstring says "in the thread", so it would need a small tweak too.)

TASK_KWARGS always sets thread_ts, so the new tests only cover mentions inside a thread. Add a case with thread_ts=None that asserts the ephemeral is sent with thread_ts="". If you've already seen this render for a top-level mention, ignore this comment.

Written by an AI agent and included in this review by its author.

assert second_data.missing_scope_settings_url is None

@patch("sentry.seer.entrypoints.slack.entrypoint.send_thread_update", return_value="1.1")
def test_on_agent_update_out_of_credits_replies_once(self, mock_send: MagicMock) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Two new on_agent_update tests only repeat what later tests already catch

Two of the seven new tests don't catch any bug the others miss:

  • test_on_agent_update_out_of_credits_replies_once (this one). It catches two bugs: the run-level OUT_OF_CREDITS branch being removed, or its key in replies check being dropped. Both bugs also fail test_on_agent_update_run_and_pr_out_of_credits_share_one_notice and test_on_agent_update_out_of_credits_notice_once_per_turn. Both of those refresh twice and assert a single SeerAgentOutOfCredits.
  • test_on_agent_update_pr_out_of_credits_posts_notice_once (line 1349). test_on_agent_update_pr_out_of_credits_notice_per_push_attempt already asserts [SeerAgentResponse, SeerAgentOutOfCredits] on the first refresh, and asserts no repeat when the same state is refreshed again. The extra summary and repo_pr_states checks on the answer are covered by the existing PR-status tests.

Deleting both keeps the same coverage with less to maintain.

Written by an AI agent and included in this review by its author.

@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch from 6360888 to a5f33c0 Compare November 12, 2026 21:45

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a5f33c0. Configure here.

alexsohn1126 and others added 7 commits November 13, 2026 11:29
Slack posts the agent out-of-credits notification when a mention is
stopped by the credit check, when an agent chat turn stops for credits,
and when a PR push fails for credits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a push runs out of credits Seer marks every remaining repo with the
same error, so each repo posted its own copy of the org-level notice. The
run-level notice used a different key, so a turn where a PR failed and the
run then stopped got it from both paths.

Share one notice across all PRs that newly failed, and key the run and PR
paths on the turn so a turn gets at most one.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The out-of-credits notice for a failed PR was deduplicated on the repo,
PR number and commit SHA. A push that fails leaves the number and SHA
as they were (both unset when the PR never landed), so a retry in a
later turn of the same thread looked like the failure already reported
and got no notice.

Key the notice on the push's idempotency key instead, which Seer sets
per attempt. A failure left in the run state from an earlier turn still
stays silent.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The out-of-credits notification now has a copy per reader. These
replies don't pass who is reading yet, so they use the member copy.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…essage

The pre-check reply is private to the person who mentioned Seer, so use
their billing access directly. The replies posted when a run or a PR push
fails use the Slack user stored with the run.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@alexsohn1126
alexsohn1126 force-pushed the alexsohn/cw-2325-slack-out-of-credits-mention-replies branch from a5f33c0 to 13ec451 Compare November 13, 2026 16:33

This branch has not been deployed

No deployments
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.

3 participants