Skip to content

feat(seer-billing): Check Seer credits before starting autofix steps - #130283

Open
srest2021 wants to merge 35 commits into
masterfrom
srest2021/CW-3061-autofix-gating
Open

srest2021 wants to merge 35 commits into
masterfrom
srest2021/CW-3061-autofix-gating

Conversation

@srest2021

@srest2021 srest2021 commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Relates to CW-3061

Adds check_autofix_billing, called from all autofix entrypoints: trigger_autofix_agent, trigger_autofix_feature, trigger_push_changes and continue_single_run.

  • Token-billed orgs are checked for credits before every step, before Open PR and before a reply to a single run, and get SeerOutOfCreditsException if they can't pay. All credit checks are also separately feature-flagged.
  • Agentic triage runs aren't billed for token-billed orgs.
  • Other orgs keep the same quota check.

Autofix single run replies get their own billable operation with a placeholder estimate.

WIP followup to handle the out of credits exceptions: #130284

Return a 402 before sending a chat message when a token-billed org does not have enough Seer credits. Dashboard generation runs are not gated. can_run_seer_operation now passes orgs that are not token-billed.

Refs CW-3061
Token-billed orgs are checked for Seer credits before each Autofix step and before opening a PR, and get SeerOutOfCreditsException when they can't pay. Other orgs keep the seat-based quota check. Agentic triage runs are not gated.

Refs CW-3061
@linear-code

linear-code Bot commented Nov 6, 2026

Copy link
Copy Markdown

CW-3061

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Nov 6, 2026
@sentry

sentry Bot commented Nov 6, 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 798 0 ✅ Unchanged

⚙️ sentry-frontend Snapshot Settings

…gent-chat

# Conflicts:
#	src/sentry/seer/endpoints/organization_seer_agent_chat.py
…tofix-gating

# Conflicts:
#	src/sentry/seer/autofix/feature/dispatch.py
#	tests/sentry/seer/autofix/feature/test_dispatch.py
Chat replies to single runs continue the run through continue_single_run, which skipped billing. The run's own referrer decides, so agentic triage runs stay free.
…gent-chat

# Conflicts:
#	src/sentry/seer/endpoints/organization_seer_agent_chat.py
…tofix-gating

Check the credit check flag before the token-billed flag. has_enough_seer_credits no longer checks the flag; its callers do.
Cover orgs that aren't token-billed, group the chat credit tests after the access tests, and match the neighboring tests' names and setup.
Base automatically changed from srest2021/CW-3061-agent-chat to master November 6, 2026 20:03
…utofix-gating

# Conflicts:
#	src/sentry/seer/credits.py
Single runs are behind organizations:autofix-single-run and need their own estimate, so they're out of scope here.
Agentic triage runs skip the Seer credit check, and the Autofix endpoint accepted any referrer from the request body. Treat a client-supplied agentic triage referrer as unknown.
Restores the single run reply check, using the placeholder estimate for now.
Comment on lines +174 to +176
if referrer == AutofixReferrer.AGENTIC_TRIAGE:
logger.warning("group_ai_autofix.internal_referrer", extra={"referrer": raw})
return AutofixReferrer.UNKNOWN

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.

Make sure people can't spoof AT referrer and skip getting billed. AT is not exposed via API.

@srest2021 srest2021 changed the title feat(seer): Check Seer credits before Autofix steps and Open PR feat(seer): Check Seer credits before starting autofix steps Nov 6, 2026
@srest2021 srest2021 changed the title feat(seer): Check Seer credits before starting autofix steps feat(seer-billing): Check Seer credits before starting autofix steps Nov 6, 2026
@srest2021
srest2021 marked this pull request as ready for review November 6, 2026 21:54
@srest2021
srest2021 requested a review from a team as a code owner November 6, 2026 21:54
@srest2021
srest2021 requested a review from a team November 6, 2026 21:54

@billyvg billyvg left a comment

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.

🤖 AI-assisted review, posted on behalf of @billyvg.

Comment on lines +201 to +206
check_autofix_billing(
group,
SeerOperation.AUTOFIX_SINGLE_RUN_REPLY,
agent_run.run.referrer,
is_new_run=False,
)

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.

🤖 AI-assisted review, posted on behalf of @billyvg.

Should a user's reply to an agentic triage run skip the credit check? continue_single_run only runs when a user replies in Seer chat. agent_run.run.referrer is the run's original referrer, though, and SeerRun.referrer is set when the run starts and never updated. So every reply on a run that agentic triage started skips the check. A reply can write code and open a PR, which means a user on a token-billed org with no credits left can keep driving an agentic triage run indefinitely.

Continuing a step-based agentic triage run from the issue page does get checked, because trigger_autofix_agent passes the caller's referrer. If only agentic triage's own automated work is meant to be free, passing the reply's referrer here would match that path.

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.

Resolved in #130552

Comment on lines +851 to +856
check_autofix_billing(
group,
SeerOperation.AUTOFIX_OPEN_PR,
seer_run.referrer if seer_run else None,
is_new_run=False,
)

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.

🤖 AI-assisted review, posted on behalf of @billyvg.

Same question for Open PR. When a user clicks Open PR (issue page or Slack) on a run that agentic triage started, this skips the credit check, because the run's referrer is night_shift. A user continuing a step on that same run is checked under their own referrer, though. The completion hook's automatic push for agentic triage runs does need the run's referrer to stay free. If user-triggered pushes should be checked, one option is to use the run's referrer only when referrer == AutofixReferrer.ON_COMPLETION_HOOK, and the caller's referrer otherwise.

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.

Resolved in #130552

Co-Authored-By: Sofia Rest <sofia.rest@sentry.io>

@sehr-m sehr-m left a comment

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.

okay wait i think i get the operations for estimate gating, but a few qs for changes :))

def check_autofix_billing(
group: Group,
operation: SeerOperation,
referrer: str | 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.

don't love us gating on referrer- these are not standardized and currently there is no plan to standardize them

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.

Resolved in #130552

trigger_autofix_agent checked billing, then called trigger_autofix_feature, which checked it again with the same arguments. Keep only the dispatch check, and test a token-billed org with credit checks off.
srest2021 added a commit that referenced this pull request Nov 9, 2026
…tion (#130463)

relates to CW-2332

depends on #129563, #130283,
#130284

The chat's credit check only runs when the panel opens or the window
regains focus. If credits run out partway through a conversation, the
message box stays enabled and the next send fails with a generic error.

This rechecks credits when:
- Seer stops a reply for credits (`failure_reason: out_of_credits`)
- a send comes back 402

so the out-of-credits notice and disabled message box show right away. A
402 no longer shows "There was an error sending your message"; the
recheck brings up the notice instead.

The recheck invalidates the credit check query, like
`useExplorerAutofix` does. That needed `useSeerCreditCheck` to turn off
with `enabled` instead of `skipToken`, so the key is the same either
way.

Example (it would show any intermediate thinking as well):
<img width="402" height="615" alt="× Seer Agent I"
src="https://github.com/user-attachments/assets/c7e056e8-73a7-4a5a-be32-62bcb80e1609"
/>

---------

Co-authored-by: Billy Vong <billy@sentry.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Credit checks no longer skip runs by referrer. Agentic triage runs are checked like any other until a follow-up marks them by feature instead. Credit checks are behind seer-credit-checks, so nothing changes in production.

Refs CW-3061
@srest2021

Copy link
Copy Markdown
Member Author

I'm going to drop agentic triage gating from this PR, wiring this feature through and gating only manual iterations on AT is a bit more complicated than I thought and deserves its own PR

This branch was successfully deployed

1 active (outdated) deployment
Preview — 4e289d32 Deployed Nov 7, 2026 by vercel[bot]
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