Skip to content

feat(integrations): Add GitHub Copilot polling functionality#106670

Merged
JoshFerge merged 15 commits intomasterfrom
jferg/github-copilot-backend-polling
Jan 21, 2026
Merged

feat(integrations): Add GitHub Copilot polling functionality#106670
JoshFerge merged 15 commits intomasterfrom
jferg/github-copilot-backend-polling

Conversation

@JoshFerge
Copy link
Member

@JoshFerge JoshFerge commented Jan 21, 2026

This PR:

  • Adds polling functionality to track GitHub Copilot agent status and PR creation. We hit the task API to get the "global id" of the PR associated with our run, then use GitHub's GraphQL API to fetch the usable PR id.
  • Adds decode_agent_id, get_task_status, and get_pr_from_graphql methods to client
  • Adds poll_github_copilot_agents function to update autofix state when PRs are created

JoshFerge and others added 14 commits January 20, 2026 15:49
Add backend support for GitHub Copilot as a coding agent provider for Autofix:
- New GitHub Copilot client using Tasks API
- Integration and identity service for Copilot auth
- Update coding agent endpoint to support Copilot provider
- Feature flag for GitHub Copilot integration
- Remove redundant variable assignment in _validate_and_get_integration
- Use .get() for safer dict access in repo extraction functions
- Simplify PR artifact lookup using next() instead of manual loop
- Add explicit parentheses to tuple return for clarity
GitHub Copilot doesn't need an org-wide integration since it uses
per-user OAuth tokens. Use the client directly instead of going
through an integration wrapper class.
Slim down the PR by removing the poll_github_copilot_agents function
and related models. This can be added back in a follow-up PR.
Make the function more extensible for future user-based providers by
accepting a CodingAgentClient instance instead of hardcoding GitHub
Copilot. The caller now creates the appropriate client.
…pilot identity

Allow getsentry to override the GitHubCopilotIdentityService implementation
via the GITHUB_COPILOT_IDENTITY_SERVICE setting. This follows the same pattern
as SENTRY_QUOTAS for cross-repo service overrides.

Also add feature flag check to the coding agents POST endpoint.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tion tests

- Rename feature flag from `organizations:integrations-github-copilot` to
  `organizations:integrations-github-copilot-agent`
- Add test for providing both integration_id and provider (validation error)
- Add test for invalid provider when GitHub Copilot feature is disabled
- Remove redundant feature check from POST endpoint (already checked in
  launch_coding_agents_for_run)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move the default implementation inline to service.py. When no
GITHUB_COPILOT_IDENTITY_SERVICE setting is configured, return None
directly instead of using a separate impl.py file.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to poll GitHub Copilot agents for status updates and PR creation.
This enables tracking the progress of GitHub Copilot coding agents and updating
autofix state when PRs are created.
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Jan 21, 2026
@JoshFerge
Copy link
Member Author

@sentry review

@JoshFerge
Copy link
Member Author

bugbot review

cursor[bot]

This comment was marked as outdated.

@JoshFerge JoshFerge marked this pull request as ready for review January 21, 2026 16:17
@JoshFerge JoshFerge requested review from a team as code owners January 21, 2026 16:17
Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

logger.info(
"coding_agent.github_copilot.task_failed",
extra={"agent_id": agent_id, "task_status": task_status.status},
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed tasks without PR artifact stay stuck in RUNNING

Medium Severity

The polling logic doesn't handle the case where a task completes without creating a PR artifact, or when a PR artifact exists but get_pr_from_graphql returns None. In these scenarios, the elif task_status.status in ("failed", "error") condition is not met (since the status is "completed" or "succeeded"), so nothing happens and the agent remains in RUNNING status indefinitely. A completed task should transition to a terminal state (COMPLETED or FAILED) rather than staying in RUNNING.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in my experience with the API this doesn't happen.


# TODO: poll GitHub Copilot agents for status updates
if autofix_state and autofix_state.coding_agents and request.user.id:
poll_github_copilot_agents(autofix_state, user_id=request.user.id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Response returns stale state after polling discovers updates

Low Severity

The polling function discovers PR updates and writes them to Seer via update_coding_agent_state, but the response is built from the original autofix_state fetched before polling. When a PR is discovered during polling, the user won't see it in the current response - they'll only see it on their next GET request. This creates confusing behavior where the system knows about updates but doesn't include them in the response.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fine, we refresh very frequently

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the expectation here that the frontend continuously polls? I know right now the frontend still polls even though the run status is complete, in which case, this is okay. But if we ever decide to stop polling on the frontend when the run status is complete, isn't it possible that we never return the PR?

Copy link
Member Author

@JoshFerge JoshFerge Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in practice i think this will be very rare, if not impossible, because the way in which copilot works is that it will create the PR immediately upon running, then as it iterates it refreshes the PR description as its way of showing its progress. so by the time the run status is complete, we'll have already linked the PR.

Base automatically changed from jferg/github-copilot-backend to master January 21, 2026 17:27
@JoshFerge JoshFerge merged commit e34c2f4 into master Jan 21, 2026
66 checks passed
@JoshFerge JoshFerge deleted the jferg/github-copilot-backend-polling branch January 21, 2026 22:59
@github-actions github-actions bot locked and limited conversation to collaborators Feb 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants