Skip to content

Commit 4ff17b8

Browse files
authored
chore(llm-detector): Add GenAI Consent Check (#104060)
adds the gen ai consent + hide ai features check to the llm issue detection - since we are still using an allow list, this won't have any immediate impact but will be a necessary check once we start expanding the scope of projects allowed fixes https://linear.app/getsentry/issue/ID-1100/add-ai-consent-to-detection
1 parent 982cd52 commit 4ff17b8

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

src/sentry/tasks/llm_issue_detection.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from django.conf import settings
1010
from pydantic import BaseModel
1111

12-
from sentry import options
12+
from sentry import features, options
1313
from sentry.issues.grouptype import LLMDetectedExperimentalGroupType
1414
from sentry.issues.issue_occurrence import IssueEvidence, IssueOccurrence
1515
from sentry.issues.producer import PayloadType, produce_occurrence_to_kafka
@@ -180,7 +180,13 @@ def detect_llm_issues_for_project(project_id: int) -> None:
180180
Process a single project for LLM issue detection.
181181
"""
182182
project = Project.objects.get_from_cache(id=project_id)
183-
organization_id = project.organization_id
183+
organization = project.organization
184+
185+
has_access = features.has("organizations:gen-ai-features", organization) and not bool(
186+
organization.get_option("sentry:hide_ai_features")
187+
)
188+
if not has_access:
189+
return
184190

185191
transactions = get_transactions_for_project(
186192
project_id, limit=50, start_time_delta={"minutes": 30}
@@ -220,7 +226,7 @@ def detect_llm_issues_for_project(project_id: int) -> None:
220226

221227
seer_request = {
222228
"telemetry": [{**trace.dict(), "kind": "trace"}],
223-
"organization_id": organization_id,
229+
"organization_id": organization.id,
224230
"project_id": project_id,
225231
}
226232
response = make_signed_seer_api_request(

tests/sentry/tasks/test_llm_issue_detection.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
run_llm_issue_detection,
99
)
1010
from sentry.testutils.cases import TestCase
11+
from sentry.testutils.helpers.features import with_feature
1112
from sentry.utils import json
1213

1314

@@ -28,25 +29,35 @@ def test_run_detection_dispatches_sub_tasks(self, mock_delay):
2829
assert mock_delay.called
2930
assert mock_delay.call_args[0][0] == project.id
3031

32+
@with_feature("organizations:gen-ai-features")
3133
@patch("sentry.tasks.llm_issue_detection.get_transactions_for_project")
3234
def test_detect_llm_issues_no_transactions(self, mock_get_transactions):
35+
"""Test that the task returns early when there are no transactions."""
3336
mock_get_transactions.return_value = []
3437

3538
detect_llm_issues_for_project(self.project.id)
3639

40+
mock_get_transactions.assert_called_once_with(
41+
self.project.id, limit=50, start_time_delta={"minutes": 30}
42+
)
43+
44+
@with_feature("organizations:gen-ai-features")
3745
@patch("sentry.tasks.llm_issue_detection.get_trace_for_transaction")
3846
@patch("sentry.tasks.llm_issue_detection.get_transactions_for_project")
39-
@patch("sentry.tasks.llm_issue_detection.random.sample")
40-
def test_detect_llm_issues_no_traces(self, mock_sample, mock_get_transactions, mock_get_trace):
47+
@patch("sentry.tasks.llm_issue_detection.random.shuffle")
48+
def test_detect_llm_issues_no_traces(self, mock_shuffle, mock_get_transactions, mock_get_trace):
49+
"""Test that the task continues gracefully when traces can't be fetched."""
4150
mock_transaction = Mock()
4251
mock_transaction.name = "test_tx"
4352
mock_transaction.project_id = self.project.id
4453
mock_get_transactions.return_value = [mock_transaction]
45-
mock_sample.side_effect = lambda x, n: x
54+
mock_shuffle.return_value = None # shuffle modifies in place
4655
mock_get_trace.return_value = None
4756

4857
detect_llm_issues_for_project(self.project.id)
4958

59+
mock_get_trace.assert_called_once_with(mock_transaction.name, mock_transaction.project_id)
60+
5061
@patch("sentry.tasks.llm_issue_detection.produce_occurrence_to_kafka")
5162
def test_create_issue_occurrence_from_detection(self, mock_produce_occurrence):
5263
detected_issue = DetectedIssue(
@@ -140,6 +151,7 @@ def test_create_issue_occurrence_without_missing_telemetry(self, mock_produce_oc
140151
evidence_names = {e.name for e in occurrence.evidence_display}
141152
assert evidence_names == {"Explanation", "Impact", "Evidence"}
142153

154+
@with_feature("organizations:gen-ai-features")
143155
@patch("sentry.tasks.llm_issue_detection.produce_occurrence_to_kafka")
144156
@patch("sentry.tasks.llm_issue_detection.make_signed_seer_api_request")
145157
@patch("sentry.tasks.llm_issue_detection.get_trace_for_transaction")

0 commit comments

Comments
 (0)