-
Notifications
You must be signed in to change notification settings - Fork 3.3k
feat: add support for GitHub Copilot API integration and enhance exec… #1336
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
base: main
Are you sure you want to change the base?
Conversation
… command handling
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.
Pull Request Overview
This PR introduces support for the GitHub Copilot API alongside enhanced process-execution handling and testing.
- Adds a
GithubCopilotClient
, configures it in the provider list, agent loop, and CLI login flow. - Extends exec utilities and tests to include
pid
tracking, faster kill timeouts, zombie detection, and stronger assertions.
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
tests/raw-exec-process-group.test.ts | Include pid in results, assert it’s >0, and improve ensureProcessGone with zombie detection and SIGKILL fallback |
tests/invalid-command-handling.test.ts | Assert pid === 0 on spawn failure |
tests/cancel-exec.test.ts | Assert pid > 0 on cancellation scenarios |
src/utils/providers.ts | Register a new “githubcopilot” provider entry |
src/utils/openai-client.ts | Implement GithubCopilotClient and branch it in createOpenAIClient |
src/utils/get-api-key.tsx | Add getGithubCopilotApiKey() device-flow login with a spinner |
src/utils/agent/sandbox/raw-exec.ts & interface.ts & exec.ts | Extend ExecResult with pid and wire it through all exec paths |
src/utils/agent/agent-loop.ts | Integrate GithubCopilotClient instantiation in the agent loop |
src/cli.tsx | Handle GitHub Copilot login flags and set corresponding env var |
Comments suppressed due to low confidence (2)
codex-cli/src/utils/providers.ts:56
- [nitpick] The provider name uses inconsistent casing. Consider renaming to "GitHub Copilot" to match official branding and improve readability.
name: "GithubCopilot",
codex-cli/src/utils/openai-client.ts:115
- Overriding
authHeaders
to return an empty object may strip necessary default headers (e.g., User-Agent). Ensure essential headers aren’t unintentionally dropped.
return {};
const timeout = 1000; | ||
const deadline = Date.now() + timeout; |
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.
[nitpick] Extract this magic timeout value into a named constant or configuration so its purpose and trade-offs are clearer and reusable.
const timeout = 1000; | |
const deadline = Date.now() + timeout; | |
const deadline = Date.now() + PROCESS_TERMINATION_TIMEOUT_MS; |
Copilot uses AI. Check for mistakes.
"accept": "application/json", | ||
}), | ||
body: JSON.stringify({ | ||
client_id: "Iv1.b507a08c87ecfe98", |
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.
[nitpick] This GitHub OAuth client ID is hardcoded. Consider making it a configurable constant or retrieving it from environment or config to ease updates and testing.
Copilot uses AI. Check for mistakes.
@@ -350,6 +351,24 @@ export class AgentLoop { | |||
}); | |||
} | |||
|
|||
if (this.provider.toLowerCase() === "githubcopilot") { |
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.
This block re-instantiates oai
for GitHub Copilot after it was already created by createOpenAIClient
, leading to duplicated logic and potential configuration drift.
Copilot uses AI. Check for mistakes.
apiKey = await fetchGithubCopilotApiKey(); | ||
try { | ||
const home = os.homedir(); | ||
const authDir = path.join(home, ".codex"); | ||
const authFile = path.join(authDir, "auth.json"); | ||
fs.writeFileSync( | ||
authFile, | ||
JSON.stringify( | ||
{ | ||
GITHUBCOPILOT_API_KEY: apiKey, | ||
}, | ||
null, | ||
2, | ||
), | ||
"utf-8", | ||
); | ||
} catch { | ||
/* ignore */ | ||
} | ||
} else if (cli.flags.login) { | ||
if (provider.toLowerCase() === "githubcopilot") { | ||
apiKey = await fetchGithubCopilotApiKey(); |
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.
[nitpick] The login flow for GitHub Copilot is duplicated in multiple branches, making the CLI logic hard to follow. Consider consolidating into a single helper or clearer conditional structure.
apiKey = await fetchGithubCopilotApiKey(); | |
try { | |
const home = os.homedir(); | |
const authDir = path.join(home, ".codex"); | |
const authFile = path.join(authDir, "auth.json"); | |
fs.writeFileSync( | |
authFile, | |
JSON.stringify( | |
{ | |
GITHUBCOPILOT_API_KEY: apiKey, | |
}, | |
null, | |
2, | |
), | |
"utf-8", | |
); | |
} catch { | |
/* ignore */ | |
} | |
} else if (cli.flags.login) { | |
if (provider.toLowerCase() === "githubcopilot") { | |
apiKey = await fetchGithubCopilotApiKey(); | |
apiKey = await handleGithubCopilotLogin(); | |
} else if (cli.flags.login) { | |
if (provider.toLowerCase() === "githubcopilot") { | |
apiKey = await handleGithubCopilotLogin(); |
Copilot uses AI. Check for mistakes.
… command handling