Skip to content

Commit 3d7c81b

Browse files
authored
Merge 73c44a9 into d270eb8
2 parents d270eb8 + 73c44a9 commit 3d7c81b

File tree

6 files changed

+59
-10
lines changed

6 files changed

+59
-10
lines changed

src/sentry/feedback/endpoints/organization_feedback_categories.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from sentry.grouping.utils import hash_from_values
2727
from sentry.models.organization import Organization
2828
from sentry.seer.seer_setup import has_seer_access
29+
from sentry.seer.signed_seer_api import SeerViewerContext
2930
from sentry.utils.cache import cache
3031

3132
logger = logging.getLogger(__name__)
@@ -107,6 +108,8 @@ def get(self, request: Request, organization: Organization) -> Response:
107108
{"detail": "AI categorization is not available for this organization."}, status=403
108109
)
109110

111+
viewer_context = SeerViewerContext(organization_id=organization.id, user_id=request.user.id)
112+
110113
try:
111114
start, end = get_date_range_from_stats_period(
112115
request.GET,
@@ -192,6 +195,7 @@ def get(self, request: Request, organization: Organization) -> Response:
192195
seer_request,
193196
timeout=SEER_TIMEOUT_S,
194197
retries=SEER_RETRIES,
198+
viewer_context=viewer_context,
195199
)
196200
except Exception:
197201
logger.exception("Seer failed to generate user feedback label groups")

src/sentry/feedback/endpoints/organization_feedback_summary.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from sentry.models.group import Group, GroupStatus
1919
from sentry.models.organization import Organization
2020
from sentry.seer.seer_setup import has_seer_access
21+
from sentry.seer.signed_seer_api import SeerViewerContext
2122
from sentry.utils import metrics
2223
from sentry.utils.cache import cache
2324

@@ -35,13 +36,17 @@
3536
SEER_RETRIES = Retry(total=1, backoff_factor=3) # 1 retry after a 3 second delay.
3637

3738

38-
def get_summary_from_seer(feedback_msgs: list[str]) -> str | None:
39+
def get_summary_from_seer(
40+
feedback_msgs: list[str],
41+
viewer_context: SeerViewerContext | None = None,
42+
) -> str | None:
3943
request_body = SummarizeFeedbacksRequest(feedbacks=feedback_msgs)
4044
try:
4145
response = make_summarize_feedbacks_request(
4246
request_body,
4347
timeout=SEER_TIMEOUT_S,
4448
retries=SEER_RETRIES,
49+
viewer_context=viewer_context,
4550
)
4651
except Exception:
4752
logger.exception(
@@ -90,6 +95,8 @@ def get(self, request: Request, organization: Organization) -> Response:
9095
{"detail": "AI summaries are not available for this organization."}, status=403
9196
)
9297

98+
viewer_context = SeerViewerContext(organization_id=organization.id, user_id=request.user.id)
99+
93100
try:
94101
start, end = get_date_range_from_stats_period(
95102
request.GET,
@@ -155,7 +162,7 @@ def get(self, request: Request, organization: Organization) -> Response:
155162
if len(feedback_msgs) < MIN_FEEDBACKS_TO_SUMMARIZE:
156163
logger.error("Too few feedbacks to summarize after enforcing the character limit")
157164

158-
summary = get_summary_from_seer(feedback_msgs)
165+
summary = get_summary_from_seer(feedback_msgs, viewer_context=viewer_context)
159166
if summary is None:
160167
return Response(
161168
{"detail": "Failed to generate a summary for a list of feedbacks"}, status=500

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from sentry.models.group import GroupStatus
2828
from sentry.models.project import Project
2929
from sentry.seer.seer_setup import has_seer_access
30+
from sentry.seer.signed_seer_api import SeerViewerContext
3031
from sentry.signals import first_feedback_received, first_new_feedback_received
3132
from sentry.types.group import GroupSubStatus
3233
from sentry.utils import json, metrics
@@ -270,12 +271,16 @@ def create_feedback_issue(
270271

271272
feedback_message = event["contexts"]["feedback"]["message"]
272273

274+
viewer_context = SeerViewerContext(organization_id=project.organization_id)
275+
273276
# Spam detection.
274277
is_message_spam = None
275278
is_spam_enabled = spam_detection_enabled(project)
276279
if is_spam_enabled:
277280
# Will be None if the request fails
278-
is_message_spam = is_spam_seer(feedback_message, project.organization_id)
281+
is_message_spam = is_spam_seer(
282+
feedback_message, project.organization_id, viewer_context=viewer_context
283+
)
279284

280285
metrics.incr(
281286
"feedback.create_feedback_issue.seer_spam_detection",
@@ -300,7 +305,12 @@ def create_feedback_issue(
300305

301306
use_ai_title = should_query_seer
302307
title = truncate_feedback_title(
303-
get_feedback_title(feedback_message, project.organization_id, use_ai_title)
308+
get_feedback_title(
309+
feedback_message,
310+
project.organization_id,
311+
use_ai_title,
312+
viewer_context=viewer_context,
313+
)
304314
)
305315

306316
# Set feedback summary to the title without the "User Feedback: " prefix
@@ -335,7 +345,9 @@ def create_feedback_issue(
335345
# Generating labels using Seer, which will later be used to categorize feedbacks
336346
if should_query_seer:
337347
try:
338-
labels = generate_labels(feedback_message, project.organization_id)
348+
labels = generate_labels(
349+
feedback_message, project.organization_id, viewer_context=viewer_context
350+
)
339351
# This will rarely happen unless the user writes a really long feedback message
340352
if len(labels) > MAX_AI_LABELS:
341353
logger.info(

src/sentry/feedback/usecases/label_generation.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22

33
from sentry.feedback.lib.seer_api import LabelGenerationRequest, make_label_generation_request
4+
from sentry.seer.signed_seer_api import SeerViewerContext
45
from sentry.utils import metrics
56

67
logger = logging.getLogger(__name__)
@@ -17,7 +18,11 @@
1718

1819

1920
@metrics.wraps("feedback.generate_labels")
20-
def generate_labels(feedback_message: str, organization_id: int) -> list[str]:
21+
def generate_labels(
22+
feedback_message: str,
23+
organization_id: int,
24+
viewer_context: SeerViewerContext | None = None,
25+
) -> list[str]:
2126
"""
2227
Generate labels for a feedback message.
2328
@@ -33,6 +38,7 @@ def generate_labels(feedback_message: str, organization_id: int) -> list[str]:
3338
request,
3439
timeout=SEER_TIMEOUT_S,
3540
retries=SEER_RETRIES,
41+
viewer_context=viewer_context,
3642
)
3743
except Exception:
3844
logger.exception("Seer failed to generate user feedback labels")

src/sentry/feedback/usecases/spam_detection.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from sentry.feedback.lib.seer_api import SpamDetectionRequest, make_spam_detection_request
55
from sentry.models.project import Project
66
from sentry.seer.seer_setup import has_seer_access
7+
from sentry.seer.signed_seer_api import SeerViewerContext
78
from sentry.utils import metrics
89

910
logger = logging.getLogger(__name__)
@@ -13,7 +14,11 @@
1314

1415

1516
@metrics.wraps("feedback.spam_detection_seer")
16-
def is_spam_seer(message: str, organization_id: int) -> bool | None:
17+
def is_spam_seer(
18+
message: str,
19+
organization_id: int,
20+
viewer_context: SeerViewerContext | None = None,
21+
) -> bool | None:
1722
"""
1823
Check if a message is spam using Seer.
1924
@@ -30,6 +35,7 @@ def is_spam_seer(message: str, organization_id: int) -> bool | None:
3035
seer_request,
3136
timeout=SEER_TIMEOUT_S,
3237
retries=SEER_RETRIES,
38+
viewer_context=viewer_context,
3339
)
3440
except Exception:
3541
logger.exception("Seer failed to check if message is spam")

src/sentry/feedback/usecases/title_generation.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
GenerateFeedbackTitleRequest,
77
make_title_generation_request,
88
)
9+
from sentry.seer.signed_seer_api import SeerViewerContext
910
from sentry.utils import metrics
1011

1112
logger = logging.getLogger(__name__)
@@ -45,7 +46,11 @@ def truncate_feedback_title(title: str, max_words: int = 10) -> str:
4546

4647

4748
@metrics.wraps("feedback.ai_title_generation")
48-
def get_feedback_title_from_seer(feedback_message: str, organization_id: int) -> str | None:
49+
def get_feedback_title_from_seer(
50+
feedback_message: str,
51+
organization_id: int,
52+
viewer_context: SeerViewerContext | None = None,
53+
) -> str | None:
4954
"""
5055
Generate an AI-powered title for user feedback using Seer, or None if generation fails.
5156
@@ -67,6 +72,7 @@ def get_feedback_title_from_seer(feedback_message: str, organization_id: int) ->
6772
seer_request,
6873
timeout=SEER_TIMEOUT_S,
6974
retries=SEER_RETRIES,
75+
viewer_context=viewer_context,
7076
)
7177
except Exception:
7278
return None
@@ -88,11 +94,19 @@ def get_feedback_title_from_seer(feedback_message: str, organization_id: int) ->
8894
return None
8995

9096

91-
def get_feedback_title(feedback_message: str, organization_id: int, use_seer: bool) -> str:
97+
def get_feedback_title(
98+
feedback_message: str,
99+
organization_id: int,
100+
use_seer: bool,
101+
viewer_context: SeerViewerContext | None = None,
102+
) -> str:
92103
if use_seer:
93104
# Message is fallback if Seer fails.
94105
raw_title = (
95-
get_feedback_title_from_seer(feedback_message, organization_id) or feedback_message
106+
get_feedback_title_from_seer(
107+
feedback_message, organization_id, viewer_context=viewer_context
108+
)
109+
or feedback_message
96110
)
97111
else:
98112
raw_title = feedback_message

0 commit comments

Comments
 (0)