Repository navigation
feat(seer-billing): Check Seer credits before starting autofix steps #130283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
cbdde3a
c247328
e2855ba
33f5287
d70d6cb
58a1b63
8856cd4
c49f7ed
8e5ca8f
0ab3b10
69f5488
0f648e8
a3dae0d
f738ddf
94b979c
302de4f
0ec42da
6f7cb6f
99eb2ac
e8f415e
396779d
90c5db5
ff4faae
b86335d
245aca9
80bba23
914a60c
28e5990
766bc10
6c0043d
1c7c190
4e289d3
451f3bd
ab0d0aa
89bdfdc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ | |
| from scm.types import GetBranchProtocol, GetRepositoryProtocol | ||
| from sentry_sdk import traces | ||
|
|
||
| from sentry import features, quotas | ||
| from sentry import features | ||
| from sentry.analytics.events.autofix_events import ( | ||
| AiAutofixAgentHandoffEvent, | ||
| AiAutofixCodeChangesCompletedEvent, | ||
|
|
@@ -23,18 +23,19 @@ | |
| AiAutofixSolutionCompletedEvent, | ||
| AiAutofixSolutionStartedEvent, | ||
| ) | ||
| from sentry.constants import ENABLE_SEER_CODING_DEFAULT, DataCategory | ||
| from sentry.constants import ENABLE_SEER_CODING_DEFAULT | ||
| from sentry.integrations.services.integration import integration_service | ||
| from sentry.models.group import Group | ||
| from sentry.seer.agent.client import SeerAgentClient | ||
| from sentry.seer.agent.client_models import SeerRunState | ||
| from sentry.seer.autofix.analytics import record_autofix_event | ||
| from sentry.seer.autofix.commit_author import SeerCommitAuthor | ||
| from sentry.seer.autofix.constants import AutofixReferrer | ||
| from sentry.seer.autofix.exceptions import NoSeerQuotaException | ||
| from sentry.seer.autofix.exceptions import NoSeerQuotaException, SeerOutOfCreditsException | ||
| from sentry.seer.autofix.feature.dispatch import ( | ||
| AutofixFeatureArgs, | ||
| autofix_run_targets_other_issue, | ||
| check_autofix_billing, | ||
|
Check warning on line 38 in src/sentry/seer/autofix/autofix_agent.py
|
||
| require_autofix_run_for_group, | ||
| trigger_autofix_feature, | ||
| ) | ||
|
|
@@ -63,6 +64,7 @@ | |
| is_free_cohort_org, | ||
| read_preference_from_sentry_db, | ||
| ) | ||
| from sentry.seer.credits import SeerOperation | ||
| from sentry.seer.entrypoints.operator import ( | ||
| SeerActivityAttribution, | ||
| SeerAutofixOperator, | ||
|
|
@@ -461,19 +463,13 @@ | |
| """ | ||
| outcome = "success" | ||
| try: | ||
| # check billing quota for triggering a new autofix run | ||
| # Free cohort orgs bypass quota only when called from agentic triage | ||
| # (allow_free_cohort=True). The API endpoint never sets this flag, | ||
| # so manual triggers still require quota. | ||
| if run_id is None: | ||
| skip_quota_check = allow_free_cohort and is_free_cohort_org(group.organization) | ||
| if not skip_quota_check: | ||
| has_budget: bool = quotas.backend.check_seer_quota( | ||
| org_id=group.organization.id, | ||
| data_category=DataCategory.SEER_AUTOFIX, | ||
| ) | ||
| if not has_budget: | ||
| raise NoSeerQuotaException() | ||
| check_autofix_billing( | ||
| group, | ||
| step.seer_operation, | ||
| referrer, | ||
| is_new_run=run_id is None, | ||
| skip_quota_for_free_cohort=allow_free_cohort, | ||
| ) | ||
|
Check warning on line 472 in src/sentry/seer/autofix/autofix_agent.py
|
||
|
srest2021 marked this conversation as resolved.
Resolved
srest2021 marked this conversation as resolved.
Resolved
|
||
|
|
||
| if run_id is not None: | ||
| _assert_existing_run_belongs_to_group(group, run_id) | ||
|
|
@@ -548,7 +544,12 @@ | |
| actor_user_id=actor_user_id, | ||
| ) | ||
| return feature_run | ||
| except (NoSeerQuotaException, SeerPermissionError, PrIterationNoPullRequestException): | ||
| except ( | ||
| NoSeerQuotaException, | ||
| SeerOutOfCreditsException, | ||
| SeerPermissionError, | ||
| PrIterationNoPullRequestException, | ||
| ): | ||
| outcome = "declined" | ||
| raise | ||
| except BaseException: | ||
|
|
@@ -839,6 +840,17 @@ | |
| ): | ||
| raise PermissionDenied("Code generation is disabled for this organization") | ||
|
|
||
| seer_run = SeerRun.objects.filter( | ||
| organization_id=group.organization.id, seer_run_state_id=run_id | ||
| ).first() | ||
| # Open PR always continues a run, so it never uses quota. | ||
| check_autofix_billing( | ||
| group, | ||
| SeerOperation.AUTOFIX_OPEN_PR, | ||
| seer_run.referrer if seer_run else None, | ||
| is_new_run=False, | ||
| ) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolved in #130552 |
||
|
|
||
|
Check warning on line 853 in src/sentry/seer/autofix/autofix_agent.py
|
||
| client = get_autofix_agent_client(group, user=user) | ||
|
|
||
| if state is None: | ||
|
|
@@ -856,10 +868,6 @@ | |
| ) | ||
| ) | ||
|
|
||
| seer_run = SeerRun.objects.filter( | ||
| organization_id=group.organization.id, seer_run_state_id=run_id | ||
| ).first() | ||
|
|
||
| # Draft when review-request/CI-green is enabled; mark ready once green fires. | ||
| client.push_changes( | ||
| run_id, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.