Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
842dd56
docs: add design spec for GHE Copilot provider
Jul 16, 2026
3f94370
feat(mitm): add GHE Copilot target descriptor
Jul 16, 2026
1ff6d13
feat(executors): add GheCopilotExecutor for GHE Copilot
Jul 16, 2026
b90a032
feat(executors): register GheCopilotExecutor in factory
Jul 16, 2026
5b6b999
feat(providers): add ghe-copilot provider with gheUrl validation
Jul 16, 2026
680f27b
feat(providers): add ghe-copilot to OAUTH_PROVIDERS and enforce HTTPS…
Jul 16, 2026
bb9993d
test(ghe-copilot): add unit tests for GheCopilotExecutor and GHE_COPI…
Jul 16, 2026
5d14838
feat: complete GHE Copilot provider implementation
Jul 16, 2026
609626c
feat: register ghe-copilot provider in registry
Jul 16, 2026
5eb767a
feat: wire ghe-copilot into OAuth flow with per-connection gheUrl
Jul 16, 2026
bc87c98
feat: add ghe-copilot device-code UI with gheUrl input
Jul 16, 2026
72606ce
fix: thread gheUrl through GHE Copilot pollToken + postExchange
Jul 16, 2026
4408bcb
fix: GHE Copilot chat routing + account test
Jul 16, 2026
8eccde7
fix: drop stream:false for GHE Copilot
Jul 16, 2026
55173fe
fix: force stream:true upstream for GHE Copilot (streaming-only proxy)
Jul 16, 2026
bcb8fec
fix: GHE Copilot live model discovery from copilotProxyUrl/models
Jul 16, 2026
ad0e99d
fix: GHE Copilot uses endpoints.api host for chat + model discovery
Jul 16, 2026
f3040af
feat(providers): finalize GHE Copilot implementation and add changelo…
Jul 17, 2026
f089d88
fix(providers): resolve ghe-copilot no-explicit-any + complexity ratchet
Jul 18, 2026
e2e20a2
merge: sync feature/ghe-copilot-provider with release/v3.8.49
diegosouzapw Jul 19, 2026
d9cbcbc
Merge remote-tracking branch 'origin/release/v3.8.49' into feature/gh…
diegosouzapw Jul 19, 2026
d1b18f8
Merge remote-tracking branch 'origin/release/v3.8.49' into HEAD
diegosouzapw Jul 19, 2026
04adb9a
fix(oauth): unblock #7546 file-size gate for GHE Copilot OAuth provider
hppsc1215 Jul 19, 2026
fa678d5
merge: reconcile release/v3.8.49 into GHE Copilot OAuth provider PR
hppsc1215 Jul 20, 2026
3e38b8d
chore(ghe-copilot): drop planning spec from docs/ and revert out-of-s…
hppsc1215 Jul 20, 2026
6c66531
fix(oauth): validate gheUrl (HTTPS-only) at both raw entry points of …
hppsc1215 Jul 20, 2026
d2edee6
chore(quality): extend oauth route file-size note for the gheUrl vali…
hppsc1215 Jul 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/features/7546-ghe-copilot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **feat(providers):** Complete GHE Copilot OAuth provider implementation with device-code flow, validation, error sanitization, and DNS provisioning mapping ([#7546](https://github.com/diegosouzapw/OmniRoute/pull/7546))
6 changes: 4 additions & 2 deletions config/quality/file-size-baseline.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"_rebaseline_2026_07_19_7546_ghe_copilot_route": "PR #7546 (GHE Copilot OAuth provider) own growth: oauth/[provider]/[action]/route.ts 960->963 (gate units, +3 = ghe-copilot device-code wiring at the existing multi-provider device-code branch — reading + HTTPS-validating the gheUrl search param (isValidGheUrl guards at both raw entry points, security-review hardening, 963->970), adding ghe-copilot to the no-PKCE provider set, and building the provider config override / threading gheUrl through poll->postExchange extraData). Mirrors the existing kiro/amazon-q startUrl override pattern right above it in the same branch; cohesive with the existing device-code dispatch chokepoint, not separately extractable without splitting a single provider-switch mid-branch. Frozen so can only shrink; structural shrink tracked in #3501.",
"_rebaseline_2026_07_19_6846_nvidia_concurrency_gate": "Issue #6846 Phase 1 (nvidia NIM local RPM budget + per-model lockout + per-connection concurrency cap) own growth: open-sse/executors/default.ts 877->890 (+13 = the irreducible call-site wiring at DefaultExecutor.execute(), the only place nvidia requests dispatch through — the existing session-pool body was extracted verbatim into a new private executeWithSessionPool() so the outer execute() can wrap it in the nvidia concurrency-gate acquire/finally-release). All actual gating logic (semaphore key + cap resolution) lives in the new leaf open-sse/executors/default/nvidiaConcurrencyGate.ts (not frozen, well under cap). Covered by tests/unit/nvidia-quota-phase1.test.ts.",
"_rebaseline_2026_07_18_v3849_provider_detail_wiring": "Merge campaign R2/R3 (2026-07-18): three authorized PRs each add irreducible call-site wiring to ProviderDetailPageClient.tsx — #7360 +5 (ProviderQuotaVisibilityToggle render, component extracted), #7419 +4 (NoAuthProviderControls wiring), #7062 +3 (Dahl provider hook) = 786->798. All three follow the extracted-component pattern (AgentrouterConsoleFields precedent); the frozen file only takes the wiring. Structural shrink tracked in #3501.",
"_rebaseline_2026_07_18_pr7653_chat_tracker_import": "PR #7653 merge-interaction growth: release moved chat.ts to its 1796 cap while this PR adds the single side-effect import 'quotaTrackersBatch.ts' (line 130) — chat.ts IS the canonical quota-fetcher registration point (codex/bailian/deepseek/openrouter/opencode/generic all import+register there), so the +1 is irreducible call-site wiring. 1796->1797. Covered by tests/unit/{agentrouter,v0,freemodel}-quota-fetcher.test.ts.",
Expand Down Expand Up @@ -239,7 +240,7 @@
"src/app/(dashboard)/dashboard/usage/components/BudgetTab.tsx": 1016,
"src/app/(dashboard)/dashboard/usage/components/EvalsTab.tsx": 2148,
"src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx": 1127,
"src/app/api/oauth/[provider]/[action]/route.ts": 960,
"src/app/api/oauth/[provider]/[action]/route.ts": 970,
"src/app/api/providers/[id]/models/route.ts": 2593,
"src/app/api/providers/[id]/test/route.ts": 940,
"src/app/api/usage/analytics/route.ts": 948,
Expand All @@ -265,7 +266,8 @@
"_rebaseline_2026_06_27_5193_5203_antigravity_oauthmodal": "Antigravity remote-login own growth: OAuthModal.tsx 960->969 (gate units). #5193 (+~4: remote paste instruction shown for all remote incl. Google + its rationale comment) and #5203 (+~5: handleManualSubmit credential-blob branch + button guard; submit logic extracted to oauthBlobSubmit.ts to minimize). Frozen set to the SUM so either merge order passes. Cohesive at the existing manual-submit chokepoint.",
"_rebaseline_2026_07_18_7399_xai_oauth_modal": "PR #7399 (xAI OAuth PKCE) own growth: OAuthModal.tsx 993->998 (+5 = provider entry + PKCE flow branch wiring at the existing provider-switch chokepoint; the provider logic itself lives in src/lib/oauth/providers/xai-oauth.ts, new leaf). Third irreducible wiring bump on this modal (969->989->993->998); structural shrink tracked in #3501.",
"_rebaseline_2026_07_19_6636_codex_session_json": "#6636 own growth: OAuthModal.tsx 998->1030 (gate units, split(\"\\n\").length incl. trailing newline; +32 = session-JSON paste branch for handleManualSubmit plus a shared submitCodexAccessToken() helper extracted from the pre-existing bare-JWT branch, mirroring the #5203 oauthBlobSubmit.ts extraction precedent; the normalizer logic itself lives in the new src/lib/oauth/utils/codexSessionImport.ts leaf module, not here). Fourth irreducible wiring bump on this modal (969->989->993->998->1030); structural shrink tracked in #3501.",
"src/shared/components/OAuthModal.tsx": 1030,
"_rebaseline_2026_07_19_7546_ghe_copilot_modal": "PR #7546 (GHE Copilot OAuth provider) own growth: OAuthModal.tsx 1030->1056 (gate units). Adds a gheUrl input state, routes ghe-copilot through the existing device-code branch, and threads gheUrl into the device-code request/poll extraData at the existing provider-switch chokepoints (+~24 lines, cohesive with the same pattern as #7399/#6636). The standalone GHE enterprise-URL config step JSX (originally +31 lines inline) was extracted to the new src/shared/components/oauthModal/GheConfigStep.tsx leaf component to minimize the bump; what remains is the irreducible provider-branch wiring. Fifth bump on this modal (969->989->993->998->1030->1056); structural shrink tracked in #3501.",
"src/shared/components/OAuthModal.tsx": 1056,
"src/shared/components/RequestLoggerV2.tsx": 1629,
"src/shared/components/analytics/charts.tsx": 1558,
"_rebaseline_2026_07_10_6318_omp_letta": "PR #6318 (@hamsa0x7, omp+letta CLI integrations) own growth: cliTools.ts (+53 = 2 registry entries incl. omp docsUrl) and cliRuntime.ts (+18 = runtime-detection wiring for the 2 new tools). Cohesive registry/wiring growth at the existing chokepoints; scope reduced from the original 5 tools (pi/codewhale/jcode shipped separately).",
Expand Down
2 changes: 2 additions & 0 deletions open-sse/config/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { lmarenaProvider } from "./registry/lmarena/index.ts";
import { kilocodeProvider } from "./registry/kilocode/index.ts";
import { github_modelsProvider } from "./registry/github/models/index.ts";
import { githubProvider } from "./registry/github/index.ts";
import { gheCopilotProvider } from "./registry/ghe-copilot/index.ts";
import { difyProvider } from "./registry/dify/index.ts";
import { ovhcloudProvider } from "./registry/ovhcloud/index.ts";
import { claudeProvider } from "./registry/claude/index.ts";
Expand Down Expand Up @@ -224,6 +225,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
kilocode: kilocodeProvider,
"github-models": github_modelsProvider,
github: githubProvider,
"ghe-copilot": gheCopilotProvider,
dify: difyProvider,
ovhcloud: ovhcloudProvider,
claude: claudeProvider,
Expand Down
156 changes: 156 additions & 0 deletions open-sse/config/providers/registry/ghe-copilot/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import type { RegistryEntry } from "../../shared.ts";
import {
GPT_5_5_CODEX_CAPABILITIES,
getGitHubCopilotChatHeaders,
resolvePublicCred,
} from "../../shared.ts";

export const gheCopilotProvider: RegistryEntry = {
id: "ghe-copilot",
alias: "ghe-copilot",
format: "openai",
executor: "ghe-copilot",
// GHE Copilot proxy is streaming-only: it rejects `stream: false` (and an
// absent stream flag). forceStream makes chatCore send stream:true upstream
// and drain the SSE back into a single JSON response for non-stream clients.
forceStream: true,
baseUrl: "https://api.githubcopilot.com/chat/completions",
responsesBaseUrl: "https://api.githubcopilot.com/responses",
authType: "oauth",
authHeader: "bearer",
// GHE Copilot requires a custom gheUrl (set per-connection via providerSpecificData).
// The executor overrides URL building + token refresh to hit the GHE host.
oauth: {
clientIdEnv: "GITHUB_OAUTH_CLIENT_ID",
clientIdDefault: resolvePublicCred("github_copilot_id"),
},
defaultContextLength: 128000,
headers: getGitHubCopilotChatHeaders(),
models: [
{
id: "claude-fable-5",
name: "Claude Fable 5",
contextLength: 1000000,
maxOutputTokens: 64000,
},
{
id: "claude-opus-4.8-fast",
name: "Claude Opus 4.8 (fast mode)",
contextLength: 1000000,
maxOutputTokens: 64000,
unsupportedParams: ["temperature", "top_p", "top_k"],
},
{
id: "claude-opus-4.8",
name: "Claude Opus 4.8",
contextLength: 1000000,
maxOutputTokens: 64000,
unsupportedParams: ["temperature", "top_p", "top_k"],
},
{
id: "claude-opus-4.7",
name: "Claude Opus 4.7",
contextLength: 1000000,
maxOutputTokens: 64000,
},
{
id: "claude-sonnet-4.6",
name: "Claude Sonnet 4.6",
contextLength: 1000000,
maxOutputTokens: 64000,
},
{
id: "claude-opus-4.5",
name: "Claude Opus 4.5",
contextLength: 200000,
maxOutputTokens: 32000,
},
{
id: "claude-sonnet-5",
name: "Claude Sonnet 5",
contextLength: 1000000,
maxOutputTokens: 64000,
},
{
id: "claude-sonnet-4.5",
name: "Claude Sonnet 4.5",
contextLength: 200000,
maxOutputTokens: 32000,
},
{
id: "claude-haiku-4.5",
name: "Claude Haiku 4.5",
contextLength: 200000,
maxOutputTokens: 32000,
},
{
id: "gemini-3.1-pro-preview",
name: "Gemini 3.1 Pro",
contextLength: 1000000,
maxOutputTokens: 64000,
},
{
id: "gemini-3.5-flash",
name: "Gemini 3.5 Flash",
contextLength: 1000000,
maxOutputTokens: 64000,
},
{ id: "gpt-5.5", name: "GPT-5.5", ...GPT_5_5_CODEX_CAPABILITIES, maxOutputTokens: 128000 },
{
id: "gpt-5.4",
name: "GPT-5.4",
supportsXHighEffort: true,
contextLength: 1050000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.4-mini",
name: "GPT-5.4 mini",
contextLength: 400000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.3-codex",
name: "GPT-5.3-Codex",
contextLength: 400000,
maxOutputTokens: 128000,
},
{
id: "gpt-5-mini",
name: "GPT-5 mini",
contextLength: 264000,
maxOutputTokens: 64000,
},
{
id: "gpt-4o-2024-11-20",
name: "GPT-4o",
contextLength: 128000,
maxOutputTokens: 16384,
},
{ id: "gpt-4o-mini", name: "GPT-4o mini", contextLength: 128000, maxOutputTokens: 4096 },
{
id: "gpt-4-0125-preview",
name: "GPT 4 Turbo",
contextLength: 128000,
maxOutputTokens: 4096,
},
{
id: "kimi-k2.7-code",
name: "Kimi K2.7 Code",
contextLength: 256000,
maxOutputTokens: 32000,
},
{
id: "mai-code-1-flash",
name: "MAI-Code-1-Flash",
contextLength: 256000,
maxOutputTokens: 128000,
},
{
id: "oswe-vscode-prime",
name: "Raptor mini",
contextLength: 264000,
maxOutputTokens: 64000,
},
],
};
Loading