feat: Add GitHub Copilot as a model provider for inference#192
Open
jyje wants to merge 16 commits into
Open
Conversation
Adds `copilot` as a selectable OpenWiki provider backed by the OpenAI-compatible GitHub Copilot API (https://api.githubcopilot.com), authenticated via the COPILOT_API_KEY environment variable. Resolves langchain-ai#34 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
Verified locally against api.githubcopilot.com: GitHub OAuth tokens (gh auth token) work as-is as bearer tokens, so no copilot_internal token exchange is needed. Also fix the Claude Haiku model ID to match the Copilot catalog (claude-haiku-4.5) and document supported token types (fine-grained PAT requires the "Copilot Requests" permission). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
The Copilot API refuses PATs for third-party integrations regardless of permissions (verified empirically; only the first-party Copilot CLI flow accepts them). Fail fast with actionable guidance instead of surfacing the raw HTTP 400 from the API. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
Verified against the live Copilot API: GPT-5-family models are only served through /responses, while other models (Claude, GPT-5.4-mini, etc.) use /chat/completions. The Copilot-Integration-Id/Editor-Version headers turned out to be unnecessary for either path, so they're removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
Reverse-engineered Copilot backends (e.g. ericc-ch/copilot-api) show that the api.githubcopilot.com endpoint only accepts OAuth tokens issued by an allow-listed first-party client (VS Code, gh CLI, the Copilot CLI) -- not arbitrary OAuth Apps or PATs. Rather than embedding a borrowed client_id to run our own device flow (what those reverse-engineered proxies do), OpenWiki delegates to the official `gh` CLI, which is already an allow-listed client: - At the Copilot credential step in `openwiki --init`, silently probe `gh auth token`. If a session exists, offer to reuse it with a single Enter press instead of requiring a manual paste. - If no session is found, surface `gh`'s own interactive device-flow login inline (Tab key), temporarily releasing Ink's raw-mode control of stdin so `gh auth login`'s own prompts render correctly, then restoring it afterward. - Manual token entry remains available as a fallback for environments without the GitHub CLI installed. The GitHub Copilot CLI's own token store was intentionally left out of scope: it has no documented "print current token" command, and its storage format isn't guaranteed to stay stable across releases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
The probe effect listed copilotAuth.kind in its dependency array, so
the setCopilotAuth({ kind: "checking" }) call inside the effect
immediately re-triggered it: React ran the previous run's cleanup,
flipping the `cancelled` flag before the async gh probe resolved. The
result was a credential prompt stuck on "Checking for an existing
GitHub CLI session..." where Tab was ignored and Enter surfaced
"COPILOT_API_KEY is required."
Guard the probe with a ref and depend only on step/provider, so it
runs exactly once per setup and its resolution is no longer discarded.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
…ilot-provider # Conflicts: # README.md # src/agent/index.ts # src/cli.tsx # src/env.ts
- Verify model options against the real GitHub Copilot API model list and add gpt-5.5, gpt-5.4-mini, claude-opus-4.8, claude-sonnet-5, claude-sonnet-4.6, claude-haiku-4.5, claude-fable-5, and gemini-2.5-pro. - Add COPILOT_BASE_URL_ENV_KEY so the copilot provider supports an alternative endpoint override (e.g. GHE.com data residency, a proxied gateway), mirroring the existing ANTHROPIC_BASE_URL pattern. Wired through PROVIDER_CONFIGS.copilot.baseUrlEnvKey, MANAGED_ENV_KEYS, isNonSecretDiagnosticKey, and the debug-value URL masking list. - Document COPILOT_BASE_URL in README's Alternative base URLs section. - Extend test/constants.test.ts's resolveProviderBaseUrl coverage with a copilot override case. 87/87 tests pass.
|
When this is getting closed |
* bump langchain-openai dep (langchain-ai#232) * openai langchain version bump (langchain-ai#241) * feat: Make OpenWiki general purpose (langchain-ai#48) * feat: Make general purpose * cr * cr * fix gmail * make it much better * add cron hooks * better ngrok * write wiki to root * cr * Harrison/vibe code (langchain-ai#109) * some vibe coding * cr * cr * cr * cr * fix gh action --------- Co-authored-by: bracesproul <braceasproul@gmail.com> * update readme * fix oauth link clicking * drop just openwiki --init * fix: oauth connection flow * improve prompting * cr * cr * brain->personal (langchain-ai#226) * cr * write instructions to INSTRUCTIONS.md file * cr --------- Co-authored-by: Harrison Chase <hw.chase.17@gmail.com> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> * fix: Update readme description (langchain-ai#242) * fix: add configurable provider retry attempts (langchain-ai#239) * fix: add OPENAI_COMPATIBLE_API_KEY to secret redaction list (langchain-ai#245) The sanitizeDiagnosticText function redacted secrets for 6 provider API keys but was missing OPENAI_COMPATIBLE_API_KEY. Users of the openai-compatible provider could have their API keys leaked in error messages. Added OPENAI_COMPATIBLE_API_KEY_ENV_KEY to both the import and the redaction loop in diagnostics.ts, and added a test case to verify the redaction works. Co-authored-by: Test User <test@example.com> * fix: constrain init update writes to openwiki (langchain-ai#230) Co-authored-by: Eva <eva@100yen.org> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> * feat: add OpenAI ChatGPT-login provider (Codex OAuth) (langchain-ai#151) * feat: add OpenAI ChatGPT-login provider (Codex OAuth) Add an `openai-chatgpt` provider that authenticates model calls with a ChatGPT/Codex OAuth login instead of a metered API key, so usage draws on the ChatGPT subscription's included Codex usage. It reuses `@langchain/openai`'s ChatOpenAI Responses-API integration pointed at the Codex backend (`useResponsesApi` + `zdrEnabled` for `store: false`, base URL and account/originator/beta headers), so DeepAgents' tool-calling and streaming keep working with zero changes to the agent harness. Two Codex-backend quirks are handled at model construction: forcing `stream: true`, and rewriting the `system` input role to `developer`. Includes a PKCE browser login + token refresh, an `oauth-login` step in the existing credential wizard, token persistence in `~/.openwiki/.env`, tests, and docs. * feat: make ChatGPT login URL copyable (borderless render + c-to-copy via OSC 52) * feat: let users paste the ChatGPT OAuth callback URL/code to finish login Adds a manual-paste fallback to the browser login: while the loopback callback server waits, the user can paste the redirect URL (or bare code) into the wizard and press Enter to complete the login in-process. Removes the need to curl the callback or set up SSH port forwarding on remote hosts. Whichever arrives first — browser callback or pasted value — wins. * feat: show ChatGPT account info and re-ask model after login - Decode the signed-in email and plan (plus/pro/etc.) from the access-token JWT, persist them, show them in the ChatGPT login step, and add an "account:" line to the run header. - Continue to the model and LangSmith steps after the ChatGPT login just like the API-key providers. Selecting a provider in the wizard now re-asks for the model even if one is stored, so a stale model id from a previous provider is not carried over. * refactor: address review feedback on the ChatGPT login provider - Centralize the CodexTokens <-> env mapping in openai-chatgpt-oauth.ts as codexTokensToEnv() and readCodexTokensFromEnv(), and use them from both the agent's refresh-at-startup and the credential wizard. The env contract now lives next to the type it serializes and is tested with the OAuth flow. readCodexTokensFromEnv() also returns null on a partial token set, so a leftover access token without an account id no longer looks signed in. - Move formatChatGptAccount() into the same module and use it from cli.tsx instead of a second copy. - Fix opening the browser on Windows. Under shell: true, cmd treats the & in the auth URL's query string as a command separator and mangles the URL. Use cmd /c start with a quoted URL and windowsVerbatimArguments instead. * fix succ login msg --------- Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> Co-authored-by: bracesproul <braceasproul@gmail.com> * fix assertion (langchain-ai#255) * docs: add github issue templates (langchain-ai#172) * docs: add GitHub issue templates * convert to yaml and add config --------- Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> Co-authored-by: Colin Francis <colin.francis@langchain.dev> * fix (langchain-ai#254) * docs: document windows bun installation requirements (langchain-ai#217) * fix: warn on Windows Bun installs * add .cjs to esling config * fix: document Windows Bun installation requirements --------- Co-authored-by: akyourowngames <akyourowngames@users.noreply.github.com> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> Co-authored-by: Colin Francis <colin.francis@langchain.dev> * feat: add GPT-5.6 OpenAI model options (langchain-ai#252) * feat: add GPT-5.6 OpenAI model options Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com> * fix failing test --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> Co-authored-by: Colin Francis <colin.francis@langchain.dev> * fix(agent): keep init update checkpoints ephemeral (langchain-ai#259) Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> * fix: keep typeof check to reject unsupported source instance targets in cron commands (langchain-ai#246) The cron pause/resume/delete commands only support string targets (connector IDs or 'all'). Source instance targets are not yet supported by the schedule functions. The typeof check correctly rejects them. Added tests verifying source instance targets are properly rejected. Co-authored-by: Test User <test@example.com> Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> * fix: Improve code onboarding, save INSTRUCTIONS.md to openwiki/ (langchain-ai#264) * fix: Improve code onboarding, save INSTRUCTIONS.md to openwiki/ * cr * fix: chatgpt login with 5.6-luna (langchain-ai#268) * fix: chatgpt login with 5.6-luna * cr * release: 0.1.1 (langchain-ai#269) --------- Co-authored-by: Colin Francis <131073567+colifran@users.noreply.github.com> Co-authored-by: Brace Sproul <braceasproul@gmail.com> Co-authored-by: Harrison Chase <hw.chase.17@gmail.com> Co-authored-by: Abhishek Ranjan <aviranjan444@gmail.com> Co-authored-by: Himanshu Kumar <145797211+himanshu231204@users.noreply.github.com> Co-authored-by: Test User <test@example.com> Co-authored-by: Eva <admin@100yen.org> Co-authored-by: Eva <eva@100yen.org> Co-authored-by: Yassine Mhirsi <98828473+Yassine-Mhirsi@users.noreply.github.com> Co-authored-by: sarthug <smpingale2469@gmail.com> Co-authored-by: Colin Francis <colin.francis@langchain.dev> Co-authored-by: Krish <animeit158@gmail.com> Co-authored-by: akyourowngames <akyourowngames@users.noreply.github.com> Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com> Co-authored-by: zan22ye <iwillgotothemoon@163.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Records merge ancestry with upstream/main so GitHub recomputes the PR langchain-ai#192 merge-base. The tree is unchanged: the squash-merged #7 already contains all upstream changes plus the conflict resolution. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017XjawjWsUJb2MhBXQGp79f
…ilot-provider Syncs with upstream 0.1.1+ (9 new commits, most notably NVIDIA NIM (langchain-ai#42) landing on main). Four files conflicted, all additive side-by-side insertions from the two providers being added in parallel; resolved by keeping both sides: - README.md: kept the GitHub Copilot section, merged NVIDIA NIM into the provider list intro sentence. - src/cli.tsx: merged both providers into the invalid-provider error message. - test/constants.test.ts, test/redaction.test.ts: union of both providers' assertions (isValidModelId/isValidProvider/ resolveProviderBaseUrl/getDefaultModelId cases, and the COPILOT_API_KEY/NVIDIA_API_KEY redaction test pairs). src/constants.ts, src/diagnostics.ts, and src/env.ts auto-merged cleanly. Verified: format:check, lint:check, typecheck, build, and pnpm test (199/199) all pass after resolution. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GjNFojcfsEnwPRSkhqcxbt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds GitHub Copilot as a supported inference provider, so teams can reuse an existing Copilot subscription instead of provisioning a separate inference API key.
Closes #34, closes #30.
What's included
copilotentry inPROVIDER_CONFIGS(src/constants.ts), routed through the OpenAI-compatible Copilot API (https://api.githubcopilot.com).COPILOT_API_KEYmust be a GitHub OAuth token (e.g.gh auth token); Personal Access Tokens are rejected early with a clear error, since the Copilot API doesn't accept them for third-party integrations.gh auth loginsession exists, OpenWiki detects and offers to reuse it during onboarding — no manual token entry needed.copilot-4-cliintegrator, keeping only confirmed-available IDs:gpt-5.5,gpt-5.4-mini,claude-opus-4.8,claude-sonnet-5,claude-sonnet-4.6,claude-haiku-4.5,claude-fable-5,gemini-2.5-pro.COPILOT_BASE_URLenv var overrides the default endpoint (e.g. GHE.com data-residency hosts, proxied gateways), mirroring the existingANTHROPIC_BASE_URLpattern.COPILOT_API_KEYis redacted from error/debug output like other provider keys.COPILOT_BASE_URLdocumented under "Alternative base URLs".Testing
Unit tests —
pnpm run format:check && pnpm run lint:check && pnpm run build && pnpm exec vitest run— 87/87 pass, including new/extended coverage intest/constants.test.ts(provider validity, default model, base URL override) andtest/redaction.test.ts(COPILOT_API_KEYredaction).Manual end-to-end verification against the real GitHub Copilot API via
pnpm run dev:Initial onboarded state — provider and model persisted to

~/.openwiki/.env, no re-prompt needed./provider— GitHub Copilot listed alongside all other providers, correctly marked as current./model— full Copilot model catalog listed and selectable.Real chat response from

gemini-2.5-pro.Real chat response from

claude-fable-5.All five confirm the provider, credential reuse, model selection, and live inference path work end to end — not just the unit-level config wiring.
Any questions or suggestions are welcome