Skip to content

Commit f58f3bd

Browse files
authored
chore(seer): add cursor issue linking for explorer autofix (#106410)
Addresses AIML-2267 Follow up to [first PR](#106344) which fixed this for old autofix and not the explorer enabled path which is what all sentry users have. Problem: When seer RCA triggers the cursor integration to make a PR, we want it to include the Sentry short-id so it links back. Solution: Tell cursor in the prompt to include the short id if auto_create_pr is True Testing: Added unit tests to make sure the prompt is correct, but can only complete E2E testing once it is live for proper github/cursor integration.
1 parent 72f8e00 commit f58f3bd

File tree

2 files changed

+105
-1
lines changed

2 files changed

+105
-1
lines changed

src/sentry/seer/autofix/autofix_agent.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ def get_autofix_explorer_state(organization: Organization, group_id: int):
236236
def generate_autofix_handoff_prompt(
237237
state: SeerRunState,
238238
instruction: str | None = None,
239+
short_id: str | None = None,
239240
) -> str:
240241
"""
241242
Generate a prompt for coding agents from autofix run state.
@@ -245,6 +246,9 @@ def generate_autofix_handoff_prompt(
245246
"""
246247
parts = ["Please fix the following issue. Ensure that your fix is fully working."]
247248

249+
if short_id:
250+
parts.append(f"Include 'Fixes {short_id}' in the pull request description.")
251+
248252
if instruction and instruction.strip():
249253
parts.append(instruction.strip())
250254

@@ -332,7 +336,12 @@ def trigger_coding_agent_handoff(
332336
category_value=str(group.id),
333337
)
334338
state = client.get_run(run_id)
335-
prompt = generate_autofix_handoff_prompt(state)
339+
340+
short_id = None
341+
if auto_create_pr:
342+
short_id = group.qualified_short_id
343+
344+
prompt = generate_autofix_handoff_prompt(state, short_id=short_id)
336345

337346
return client.launch_coding_agents(
338347
run_id=run_id,

tests/sentry/seer/autofix/test_autofix_agent.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,48 @@ def test_prompt_with_both_artifacts(self):
133133
assert "## Proposed Solution" in prompt
134134
assert "Fix the handler" in prompt
135135

136+
def test_prompt_with_short_id(self):
137+
"""Test that short_id is included in prompt when provided."""
138+
state = SeerRunState(
139+
run_id=123,
140+
blocks=[],
141+
status="completed",
142+
updated_at="2024-01-01T00:00:00Z",
143+
)
144+
145+
prompt = generate_autofix_handoff_prompt(state, short_id="AIML-2301")
146+
147+
assert "Include 'Fixes AIML-2301' in the pull request description" in prompt
148+
149+
def test_prompt_without_short_id(self):
150+
"""Test that 'Fixes' is not in prompt when short_id is None."""
151+
state = SeerRunState(
152+
run_id=123,
153+
blocks=[],
154+
status="completed",
155+
updated_at="2024-01-01T00:00:00Z",
156+
)
157+
158+
prompt = generate_autofix_handoff_prompt(state, short_id=None)
159+
160+
assert "Fixes" not in prompt
161+
162+
def test_prompt_with_short_id_and_instruction(self):
163+
"""Test that both short_id and instruction are included."""
164+
state = SeerRunState(
165+
run_id=123,
166+
blocks=[],
167+
status="completed",
168+
updated_at="2024-01-01T00:00:00Z",
169+
)
170+
171+
prompt = generate_autofix_handoff_prompt(
172+
state, instruction="Focus on performance", short_id="PROJ-123"
173+
)
174+
175+
assert "Include 'Fixes PROJ-123' in the pull request description" in prompt
176+
assert "Focus on performance" in prompt
177+
136178

137179
class TestBuildStepPrompt(TestCase):
138180
def setUp(self):
@@ -501,3 +543,56 @@ def test_trigger_coding_agent_handoff_no_preferences_returns_failure(
501543
assert len(result["failures"]) == 1
502544
assert "No repositories configured" in result["failures"][0]["error_message"]
503545
mock_client.launch_coding_agents.assert_not_called()
546+
547+
@patch("sentry.seer.autofix.autofix_agent.get_project_seer_preferences")
548+
@patch("sentry.seer.autofix.autofix_agent.SeerExplorerClient")
549+
def test_trigger_coding_agent_handoff_includes_short_id_when_auto_create_pr_enabled(
550+
self, mock_client_class, mock_get_prefs
551+
):
552+
"""Test that short_id is included in prompt when auto_create_pr is True."""
553+
mock_client = MagicMock()
554+
mock_client_class.return_value = mock_client
555+
mock_client.get_run.return_value = self._make_run_state()
556+
mock_client.launch_coding_agents.return_value = {"successes": [], "failures": []}
557+
558+
# Set up preferences with auto_create_pr=True
559+
mock_get_prefs.return_value = self._make_preference_response(auto_create_pr=True)
560+
561+
trigger_coding_agent_handoff(
562+
group=self.group,
563+
run_id=123,
564+
integration_id=456,
565+
)
566+
567+
call_kwargs = mock_client.launch_coding_agents.call_args.kwargs
568+
prompt = call_kwargs["prompt"]
569+
# Prompt should contain "Fixes {short_id}" instruction
570+
assert (
571+
f"Include 'Fixes {self.group.qualified_short_id}' in the pull request description"
572+
in prompt
573+
)
574+
575+
@patch("sentry.seer.autofix.autofix_agent.get_project_seer_preferences")
576+
@patch("sentry.seer.autofix.autofix_agent.SeerExplorerClient")
577+
def test_trigger_coding_agent_handoff_excludes_short_id_when_auto_create_pr_disabled(
578+
self, mock_client_class, mock_get_prefs
579+
):
580+
"""Test that short_id is NOT included in prompt when auto_create_pr is False."""
581+
mock_client = MagicMock()
582+
mock_client_class.return_value = mock_client
583+
mock_client.get_run.return_value = self._make_run_state()
584+
mock_client.launch_coding_agents.return_value = {"successes": [], "failures": []}
585+
586+
# Set up preferences with auto_create_pr=False (default)
587+
mock_get_prefs.return_value = self._make_preference_response(auto_create_pr=False)
588+
589+
trigger_coding_agent_handoff(
590+
group=self.group,
591+
run_id=123,
592+
integration_id=456,
593+
)
594+
595+
call_kwargs = mock_client.launch_coding_agents.call_args.kwargs
596+
prompt = call_kwargs["prompt"]
597+
# Prompt should NOT contain "Fixes" instruction
598+
assert "Fixes" not in prompt

0 commit comments

Comments
 (0)