Skip to content

feat: add GitHub Copilot Provider that support agent mode #7010 #7072

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

NaccOll
Copy link

@NaccOll NaccOll commented Aug 14, 2025

Related GitHub Issue

Closes: #7010

Description

  • Implemented the Copilot component with authentication and model selection features.
  • Added tests for the Copilot component covering authentication states, error handling, and model management.
  • Updated localization files to include Copilot-related strings in multiple languages.
  • Enhanced the model validation functions to support Copilot models.
  • Modified the useSelectedModel hook to handle Copilot model selection.
  • Updated the index file to export the Copilot component.

VS Code LM API cannot achieve multiple use of the tool consuming only one advanced request. Therefore, I implemented a Copilot Provider, mimicking the Copilot authentication process found at https://github.com/BerriAI/litellm and https://github.com/sst/opencode.

In my own test, I chose claude-4 and had him write a web version of Angry Birds. This involved reading and writing eight files, requiring approximately 20 tool calls and consuming only one premium requeust.

Test Procedure

  1. Select Copilot as your service provider.
  2. Click Copilot Authentication.
  3. Copy the device code.
  4. Click Open Link.
  5. Enter the device code and wait for authentication to complete.
  6. Select a model and save.
  7. Start the task.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

image image

Documentation Updates

Additional Notes

Get in Touch


Important

Adds GitHub Copilot Provider with agent mode, including authentication, model selection, and validation, with tests and localization updates.

  • Behavior:
    • Adds CopilotHandler in copilot.ts for GitHub Copilot Provider with authentication and model selection.
    • Updates webviewMessageHandler.ts to handle Copilot authentication and model requests.
    • Supports model validation and selection in validate.ts and useSelectedModel.ts.
  • Tests:
    • Adds tests for Copilot authentication and model handling in copilot.test.ts and webviewMessageHandler.copilot.test.ts.
    • Tests for provider settings in provider-settings.copilot.test.ts.
  • Localization:
    • Updates localization files for Copilot-related strings in multiple languages.
  • Misc:
    • Adds Copilot component in ApiOptions.tsx for UI integration.
    • Updates provider-settings.ts to include Copilot schema.

This description was created by Ellipsis for 5b02f1b. You can customize this summary. It will automatically update as commits are pushed.

…7010

- Implemented the Copilot component with authentication and model selection features.
- Added tests for the Copilot component covering authentication states, error handling, and model management.
- Updated localization files to include Copilot-related strings in multiple languages.
- Enhanced the model validation functions to support Copilot models.
- Modified the useSelectedModel hook to handle Copilot model selection.
- Updated the index file to export the Copilot component.
@NaccOll NaccOll requested review from mrubens, cte and jr as code owners August 14, 2025 02:53
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. enhancement New feature or request labels Aug 14, 2025

const handler = new CopilotHandler(mockOptions)

await expect(handler.completePrompt("Test prompt")).rejects.toThrow(" Copilotetion error: API Error")
Copy link

Choose a reason for hiding this comment

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

Typographical issue: The error message string contains "Copilotetion error: API Error" which appears to be a typo. Perhaps it should be something like "Copilot completion error: API Error"?

Suggested change
await expect(handler.completePrompt("Test prompt")).rejects.toThrow(" Copilotetion error: API Error")
await expect(handler.completePrompt("Test prompt")).rejects.toThrow(" Copilot completion error: API Error")

timeout: getApiRequestTimeout(),
})
} catch (error) {
throw new Error(`Failed to authenticate with Copilot: ${error}`)
Copy link

Choose a reason for hiding this comment

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

Typographical error: The error message 'Failed to authenticate with Copilot: ...' contains an extra space before 'Copilot'. Please remove the extra space.

Suggested change
throw new Error(`Failed to authenticate with Copilot: ${error}`)
throw new Error(`Failed to authenticate with Copilot: ${error}`)

return response.choices[0]?.message.content || ""
} catch (error) {
if (error instanceof Error) {
throw new Error(` Copilotetion error: ${error.message}`)
Copy link

Choose a reason for hiding this comment

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

Typographical error: The error message ' Copilotetion error: ...' has a leading extra space and a misspelling. Consider revising it to something like 'Copilot completion error: ...' to improve clarity.

Suggested change
throw new Error(` Copilotetion error: ${error.message}`)
throw new Error(`Copilot completion error: ${error.message}`)

Copy link

@roomote roomote bot left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution! I've reviewed the GitHub Copilot Provider implementation and found it to be well-structured overall. The OAuth device flow authentication is properly implemented, and the TypeScript typing is comprehensive. However, there are some issues that need attention before merging.

timeout: getApiRequestTimeout(),
})
} catch (error) {
throw new Error(`Failed to authenticate with Copilot: ${error}`)
Copy link

Choose a reason for hiding this comment

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

Typo: There's an extra space here - should be "Copilot" not " Copilot"

Suggested change
throw new Error(`Failed to authenticate with Copilot: ${error}`)
throw new Error(`Failed to authenticate with Copilot: ${error}`)

return response.choices[0]?.message.content || ""
} catch (error) {
if (error instanceof Error) {
throw new Error(` Copilotetion error: ${error.message}`)
Copy link

Choose a reason for hiding this comment

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

Same typo here - should be "Copilot completion" not " Copilotetion"

Suggested change
throw new Error(` Copilotetion error: ${error.message}`)
throw new Error(`Copilot completion error: ${error.message}`)

}
return result
} catch (error) {
console.error("Failed to fetch Copilot:", error)
Copy link

Choose a reason for hiding this comment

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

Incomplete error message - should be "Failed to fetch Copilot models:" or similar

Suggested change
console.error("Failed to fetch Copilot:", error)
console.error("Failed to fetch Copilot models:", error)

/**
* Determine the X-Initiator header based on message roles
*/
private determineInitiator(messages: Anthropic.Messages.MessageParam[]): string {
Copy link

Choose a reason for hiding this comment

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

Is this X-Initiator logic correct? The method seems complex and the logic for determining 'agent' vs 'user' might not cover all edge cases. Could you add more comments explaining the rationale, or consider simplifying this?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah. This method is mainly used to determine whether the last request was sent by the user. However, there is currently no such flag, which can only determine whether the text in the message has the specified tag.


private constructor() {
// Store tokens in user's home directory
this.tokenDir = join(homedir(), ".roo-code", "copilot")
Copy link

Choose a reason for hiding this comment

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

Security concern: Tokens are stored in plaintext at ~/.roo-code/copilot/tokens.json. Have you considered using VSCode's secret storage API instead for better security?

Example:

await context.secrets.store('copilot_access_token', accessToken)

apiKey: "placeholder",
defaultHeaders: {
...DEFAULT_HEADERS,
"editor-version": "vscode/1.85.1",
Copy link

Choose a reason for hiding this comment

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

These version strings are hard-coded. Could they be made configurable or pulled from the actual VSCode/extension version?

Suggested change
"editor-version": "vscode/1.85.1",
"editor-version": vscode.version,
"editor-plugin-version": `copilot/${extensionVersion}`,

await this.ensureAuthenticated()

// Use the authenticated client to fetch models
const response = await fetch(`${this.client.baseURL}models`, {
Copy link

Choose a reason for hiding this comment

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

Missing rate limiting logic. GitHub APIs have rate limits - should we add retry logic with exponential backoff for resilience?

vi.mock("../transform/openai-format")
vi.mock("../transform/model-params")

describe("CopilotHandler", () => {
Copy link

Choose a reason for hiding this comment

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

Test coverage could be improved - consider adding tests for:

  • Error recovery scenarios
  • Token refresh logic
  • Rate limiting behavior
  • Full authentication flow including timeout scenarios

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Aug 14, 2025
@NaccOll NaccOll marked this pull request as draft August 14, 2025 04:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:XXL This PR changes 1000+ lines, ignoring generated files.
Projects
Status: Triage
Development

Successfully merging this pull request may close these issues.

Copilot premium requeusts via LM API
2 participants