Skip to content

Commit 39de7a4

Browse files
authored
ref(feedback): skip ai titles for spam feedback (#97448)
We should skip additional AI processing for spam
1 parent e84b4c9 commit 39de7a4

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

src/sentry/feedback/usecases/ingest/create_feedback.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,12 @@ def create_feedback_issue(
298298
event["contexts"]["feedback"], source, is_message_spam
299299
)
300300
issue_fingerprint = [uuid4().hex]
301+
301302
ai_title = None
302-
if should_get_ai_title(project.organization):
303+
if not is_message_spam and should_get_ai_title(project.organization):
303304
ai_title = get_feedback_title_from_seer(feedback_message, project.organization_id)
304305
formatted_title = format_feedback_title(ai_title or feedback_message)
306+
305307
occurrence = IssueOccurrence(
306308
id=uuid4().hex,
307309
event_id=event["event_id"],

src/sentry/feedback/usecases/title_generation.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
logger = logging.getLogger(__name__)
1515

16+
SEER_GENERATE_TITLE_URL = f"{settings.SEER_AUTOFIX_URL}/v1/automation/summarize/feedback/title"
17+
1618

1719
class GenerateFeedbackTitleRequest(TypedDict):
1820
"""Corresponds to GenerateFeedbackTitleRequest in Seer."""
@@ -128,7 +130,7 @@ def make_seer_request(request: GenerateFeedbackTitleRequest) -> bytes:
128130
serialized_request = json.dumps(request)
129131

130132
response = requests.post(
131-
f"{settings.SEER_AUTOFIX_URL}/v1/automation/summarize/feedback/title",
133+
SEER_GENERATE_TITLE_URL,
132134
data=serialized_request,
133135
headers={
134136
"content-type": "application/json;charset=utf-8",

tests/sentry/feedback/usecases/ingest/test_create_feedback.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import pytest
88
import responses
9-
from django.conf import settings
109

1110
from sentry.feedback.lib.utils import FeedbackCreationSource
1211
from sentry.feedback.usecases.ingest.create_feedback import (
@@ -19,6 +18,7 @@
1918
MAX_AI_LABELS,
2019
MAX_AI_LABELS_JSON_LENGTH,
2120
)
21+
from sentry.feedback.usecases.title_generation import SEER_GENERATE_TITLE_URL
2222
from sentry.models.group import Group, GroupStatus
2323
from sentry.signals import first_feedback_received, first_new_feedback_received
2424
from sentry.testutils.helpers import Feature
@@ -28,11 +28,11 @@
2828
from tests.sentry.feedback import create_dummy_openai_response, mock_feedback_event
2929

3030

31-
def mock_seer_response(**kwargs) -> None:
32-
"""Use with @responses.activate to mock Seer API responses."""
31+
def mock_seer_title_response(**kwargs) -> None:
32+
"""Use with @responses.activate to mock Seer title generation response."""
3333
responses.add(
3434
responses.POST,
35-
f"{settings.SEER_AUTOFIX_URL}/v1/automation/summarize/feedback/title",
35+
SEER_GENERATE_TITLE_URL,
3636
**kwargs,
3737
)
3838

@@ -944,7 +944,7 @@ def test_create_feedback_issue_title_from_seer(
944944
event = mock_feedback_event(default_project.id)
945945
event["contexts"]["feedback"]["message"] = "The login button is broken and the UI is slow"
946946

947-
mock_seer_response(
947+
mock_seer_title_response(
948948
status=200,
949949
body='{"title": "Login Button Issue"}',
950950
)
@@ -970,7 +970,7 @@ def test_create_feedback_issue_title_from_seer_fallback(
970970
event = mock_feedback_event(default_project.id)
971971
event["contexts"]["feedback"]["message"] = "The login button is broken and the UI is slow"
972972

973-
mock_seer_response(body=Exception("Network Error"))
973+
mock_seer_title_response(body=Exception("Network Error"))
974974
create_feedback_issue(event, default_project, FeedbackCreationSource.NEW_FEEDBACK_ENVELOPE)
975975

976976
assert mock_produce_occurrence_to_kafka.call_count == 1
@@ -980,6 +980,33 @@ def test_create_feedback_issue_title_from_seer_fallback(
980980
)
981981

982982

983+
@django_db_all
984+
@responses.activate
985+
def test_create_feedback_issue_title_from_seer_skips_if_spam(
986+
default_project,
987+
mock_produce_occurrence_to_kafka,
988+
) -> None:
989+
"""Test title generation endpoint is not called if marked as spam."""
990+
with (
991+
patch("sentry.feedback.usecases.ingest.create_feedback.is_spam", return_value=True),
992+
# XXX: this is not ideal to mock, we should refactor spam and AI processors to their own unit testable function.
993+
patch(
994+
"sentry.feedback.usecases.ingest.create_feedback.spam_detection_enabled",
995+
return_value=True,
996+
),
997+
Feature(
998+
{
999+
"organizations:gen-ai-features": True,
1000+
"organizations:user-feedback-ai-titles": True,
1001+
}
1002+
),
1003+
):
1004+
event = mock_feedback_event(default_project.id)
1005+
create_feedback_issue(event, default_project, FeedbackCreationSource.NEW_FEEDBACK_ENVELOPE)
1006+
urls = [call.request.url for call in responses.calls]
1007+
assert SEER_GENERATE_TITLE_URL not in urls
1008+
1009+
9831010
@django_db_all
9841011
@responses.activate
9851012
def test_create_feedback_issue_title_from_seer_none(
@@ -995,7 +1022,7 @@ def test_create_feedback_issue_title_from_seer_none(
9951022
event = mock_feedback_event(default_project.id)
9961023
event["contexts"]["feedback"]["message"] = "The login button is broken and the UI is slow"
9971024

998-
mock_seer_response(
1025+
mock_seer_title_response(
9991026
status=200,
10001027
body='{"title": ""}',
10011028
)

tests/sentry/feedback/usecases/test_title_generation.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
import pytest
66
import responses
7-
from django.conf import settings
87

98
from sentry.feedback.usecases.title_generation import (
9+
SEER_GENERATE_TITLE_URL,
1010
GenerateFeedbackTitleRequest,
1111
format_feedback_title,
1212
get_feedback_title_from_seer,
@@ -22,7 +22,7 @@ def mock_seer_response(**kwargs) -> None:
2222
"""Use with @responses.activate to mock Seer API responses."""
2323
responses.add(
2424
responses.POST,
25-
f"{settings.SEER_AUTOFIX_URL}/v1/automation/summarize/feedback/title",
25+
SEER_GENERATE_TITLE_URL,
2626
**kwargs,
2727
)
2828

@@ -78,10 +78,7 @@ def test_make_seer_request(self):
7878

7979
assert len(responses.calls) == 1
8080
seer_request = responses.calls[0].request
81-
assert (
82-
seer_request.url
83-
== f"{settings.SEER_AUTOFIX_URL}/v1/automation/summarize/feedback/title"
84-
)
81+
assert seer_request.url == SEER_GENERATE_TITLE_URL
8582
assert seer_request.method == "POST"
8683
assert seer_request.headers["content-type"] == "application/json;charset=utf-8"
8784

0 commit comments

Comments
 (0)