-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
feat(autofix): Handle PR iteration completion and introspection #117217
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 all commits
756e926
6764068
0a242bf
c26e4e4
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 |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |
| from sentry.seer.autofix.autofix_agent import ( | ||
| STEP_CONFIGS, | ||
| AutofixStep, | ||
| get_latest_iteration_index, | ||
| trigger_autofix_agent, | ||
| trigger_coding_agent_handoff, | ||
| trigger_push_changes, | ||
|
|
@@ -29,6 +30,7 @@ | |
| from sentry.seer.autofix.introspection import ( | ||
| IntrospectionDecision, | ||
| introspect_code_changes, | ||
| introspect_iteration, | ||
| introspect_root_cause, | ||
| introspect_solution, | ||
| ) | ||
|
|
@@ -167,18 +169,7 @@ def _send_step_webhook( | |
| # handled but the expectation is that we only create PRs once | ||
| # per seer run. | ||
| webhook_action_type = SeerActionType.PR_CREATED | ||
| webhook_payload["pull_requests"] = [ | ||
| { | ||
| "provider": "unknown", # TODO: we don't have the repo object readily accessible here | ||
| "repo_name": pull_request.repo_name, | ||
| "pull_request": { | ||
| "pr_id": pull_request.pr_id, | ||
| "pr_number": pull_request.pr_number, | ||
| "pr_url": pull_request.pr_url, | ||
| }, | ||
| } | ||
| for pull_request in state.repo_pr_states.values() | ||
| ] | ||
| webhook_payload["pull_requests"] = cls._format_pull_requests_payload(state) | ||
| is_pr_created = True | ||
| analytics.record( | ||
| AiAutofixPrCreatedCompletedEvent( | ||
|
|
@@ -190,20 +181,19 @@ def _send_step_webhook( | |
| ) | ||
| else: | ||
| webhook_action_type = SeerActionType.CODING_COMPLETED | ||
| diffs_by_repo = state.get_diffs_by_repo() | ||
| webhook_payload["code_changes"] = { | ||
| repo: [ | ||
| { | ||
| "diff": p.diff, | ||
| "path": p.patch.path, | ||
| "type": p.patch.type, | ||
| "added": p.patch.added, | ||
| "removed": p.patch.removed, | ||
| } | ||
| for p in patches | ||
| ] | ||
| for repo, patches in diffs_by_repo.items() | ||
| } | ||
| webhook_payload["code_changes"] = cls._format_code_changes_payload(state) | ||
| elif current_step == AutofixStep.PR_ITERATION: | ||
| # PR iteration only runs against an existing PR, so there should be pr states. | ||
| if not state.repo_pr_states: | ||
| logger.error( | ||
| "autofix.on_completion_hook.pr_iteration_missing_repo_pr_states", | ||
| extra={"run_id": run_id, "organization_id": organization.id}, | ||
| ) | ||
| webhook_action_type = SeerActionType.ITERATION_COMPLETED | ||
| iteration_index = get_latest_iteration_index(state) | ||
| webhook_payload["pull_requests"] = cls._format_pull_requests_payload(state) | ||
| webhook_payload["code_changes"] = cls._format_code_changes_payload(state) | ||
| webhook_payload["iteration_index"] = iteration_index | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| if not webhook_action_type: | ||
| return | ||
|
|
@@ -264,6 +254,38 @@ def _send_step_webhook( | |
| ) | ||
| ) | ||
|
|
||
| @classmethod | ||
|
cursor[bot] marked this conversation as resolved.
|
||
| def _format_code_changes_payload(cls, state: SeerRunState) -> dict: | ||
| diffs_by_repo = state.get_diffs_by_repo() | ||
| return { | ||
| repo: [ | ||
| { | ||
| "diff": p.diff, | ||
| "path": p.patch.path, | ||
| "type": p.patch.type, | ||
| "added": p.patch.added, | ||
| "removed": p.patch.removed, | ||
| } | ||
| for p in patches | ||
| ] | ||
| for repo, patches in diffs_by_repo.items() | ||
| } | ||
|
|
||
| @classmethod | ||
| def _format_pull_requests_payload(cls, state: SeerRunState) -> list[dict]: | ||
| return [ | ||
| { | ||
| "provider": "unknown", | ||
| "repo_name": pull_request.repo_name, | ||
| "pull_request": { | ||
| "pr_id": pull_request.pr_id, | ||
| "pr_number": pull_request.pr_number, | ||
| "pr_url": pull_request.pr_url, | ||
| }, | ||
| } | ||
| for pull_request in state.repo_pr_states.values() | ||
| ] | ||
|
|
||
| @classmethod | ||
| def _get_current_step( | ||
| cls, state: SeerRunState | ||
|
|
@@ -350,6 +372,7 @@ def _maybe_continue_pipeline( | |
| group, | ||
| ) | ||
| if decision is not None: | ||
| iteration_index = get_latest_iteration_index(state) | ||
| analytics.record( | ||
| AiAutofixIntrospectionEvent( | ||
| organization_id=organization.id, | ||
|
|
@@ -359,6 +382,7 @@ def _maybe_continue_pipeline( | |
| step=current_step.value, | ||
| action=decision.action.value, | ||
| reached_stopping_point=reached_stopping_point, | ||
| iteration_index=iteration_index, | ||
|
Contributor
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. Introspection index on wrong stepsLow Severity Every introspection analytics event now sets Reviewed by Cursor Bugbot for commit 11bbfa9. Configure here. |
||
| ) | ||
| ) | ||
| logger.info( | ||
|
|
@@ -452,7 +476,8 @@ def run_introspection( | |
| return introspect_solution(organization, run_id, state, group) | ||
| elif step == AutofixStep.CODE_CHANGES: | ||
| return introspect_code_changes(organization, run_id, state, group) | ||
|
sentry-warden[bot] marked this conversation as resolved.
|
||
| return None | ||
| elif step == AutofixStep.PR_ITERATION: | ||
| return introspect_iteration(organization, run_id, state, group) | ||
|
|
||
| @classmethod | ||
| def _push_changes(cls, group: Group, run_id: int, state: SeerRunState) -> None: | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid zero iteration index emitted
Medium Severity
When a
PR_ITERATIONblock lacksiteration_indexmetadata,get_latest_iteration_indexlogs and returns0. Iteration numbering starts at1, soITERATION_COMPLETEDwebhooks and related analytics can publish an invaliditeration_indexinstead of failing or deriving the correct value.Additional Locations (1)
src/sentry/seer/autofix/on_completion_hook.py#L191-L196Reviewed by Cursor Bugbot for commit 11bbfa9. Configure here.