@code-yeongyu/senpi-ai 2026.9.28-5 → 2026.9.28-7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/github-copilot-endpoint.d.ts +19 -0
- package/dist/api/github-copilot-endpoint.d.ts.map +1 -0
- package/dist/api/github-copilot-endpoint.js +48 -0
- package/dist/api/github-copilot-endpoint.js.map +1 -0
- package/dist/api/github-copilot-errors.d.ts.map +1 -1
- package/dist/api/github-copilot-errors.js +3 -0
- package/dist/api/github-copilot-errors.js.map +1 -1
- package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
- package/dist/auth/oauth/github-copilot.js +18 -36
- package/dist/auth/oauth/github-copilot.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/devin.models.d.ts +5 -3
- package/dist/providers/devin.models.d.ts.map +1 -1
- package/dist/providers/devin.models.js +6 -5
- package/dist/providers/devin.models.js.map +1 -1
- package/dist/providers/github-copilot.d.ts.map +1 -1
- package/dist/providers/github-copilot.js +15 -1
- package/dist/providers/github-copilot.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const GITHUB_COPILOT_INDIVIDUAL_BASE_URL = "https://api.individual.githubcopilot.com";
|
|
2
|
+
export interface GitHubCopilotApiEndpoint {
|
|
3
|
+
readonly tid: string;
|
|
4
|
+
readonly url: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function githubCopilotTokenField(token: string, key: string): string | undefined;
|
|
7
|
+
export declare function githubCopilotBaseUrlFromToken(token: string): string | undefined;
|
|
8
|
+
export declare function parseGitHubCopilotApiEndpoint(value: unknown): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* The account's Copilot API base URL, in order: the token response's `endpoints.api` recorded for
|
|
11
|
+
* this exact token (matched by `tid`, so a pooled sibling account never borrows it), the token's
|
|
12
|
+
* `proxy-ep`, the GitHub Enterprise Server domain, then the individual host.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveGitHubCopilotBaseUrl(input: {
|
|
15
|
+
token?: string;
|
|
16
|
+
apiEndpoint?: unknown;
|
|
17
|
+
enterpriseDomain?: string;
|
|
18
|
+
}): string;
|
|
19
|
+
//# sourceMappingURL=github-copilot-endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-copilot-endpoint.d.ts","sourceRoot":"","sources":["../../src/api/github-copilot-endpoint.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,kCAAkC,6CAA6C,CAAC;AAE7F,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMtF;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG/E;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAShF;AASD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAOT"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// The Copilot API host is per account plan (individual, business, enterprise, data-residency
|
|
2
|
+
// tenants). A request sent to another plan's host is refused with `421 Misdirected Request`,
|
|
3
|
+
// so the host always comes from the account's own token; the individual host is a last resort.
|
|
4
|
+
export const GITHUB_COPILOT_INDIVIDUAL_BASE_URL = "https://api.individual.githubcopilot.com";
|
|
5
|
+
export function githubCopilotTokenField(token, key) {
|
|
6
|
+
for (const part of token.split(";")) {
|
|
7
|
+
const separator = part.indexOf("=");
|
|
8
|
+
if (separator > 0 && part.slice(0, separator) === key)
|
|
9
|
+
return part.slice(separator + 1) || undefined;
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
export function githubCopilotBaseUrlFromToken(token) {
|
|
14
|
+
const proxyHost = githubCopilotTokenField(token, "proxy-ep");
|
|
15
|
+
return proxyHost ? `https://${proxyHost.replace(/^proxy\./, "api.")}` : undefined;
|
|
16
|
+
}
|
|
17
|
+
export function parseGitHubCopilotApiEndpoint(value) {
|
|
18
|
+
if (typeof value !== "string")
|
|
19
|
+
return undefined;
|
|
20
|
+
try {
|
|
21
|
+
const url = new URL(value.trim());
|
|
22
|
+
if (url.protocol !== "https:" || !url.hostname || url.username || url.password)
|
|
23
|
+
return undefined;
|
|
24
|
+
return `${url.origin}${url.pathname.replace(/\/+$/, "")}`;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function endpointForToken(endpoint, token) {
|
|
31
|
+
if (!token || typeof endpoint !== "object" || endpoint === null)
|
|
32
|
+
return undefined;
|
|
33
|
+
const tid = Reflect.get(endpoint, "tid");
|
|
34
|
+
const url = parseGitHubCopilotApiEndpoint(Reflect.get(endpoint, "url"));
|
|
35
|
+
return typeof tid === "string" && tid === githubCopilotTokenField(token, "tid") ? url : undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The account's Copilot API base URL, in order: the token response's `endpoints.api` recorded for
|
|
39
|
+
* this exact token (matched by `tid`, so a pooled sibling account never borrows it), the token's
|
|
40
|
+
* `proxy-ep`, the GitHub Enterprise Server domain, then the individual host.
|
|
41
|
+
*/
|
|
42
|
+
export function resolveGitHubCopilotBaseUrl(input) {
|
|
43
|
+
return (endpointForToken(input.apiEndpoint, input.token) ??
|
|
44
|
+
(input.token ? githubCopilotBaseUrlFromToken(input.token) : undefined) ??
|
|
45
|
+
(input.enterpriseDomain ? `https://copilot-api.${input.enterpriseDomain}` : undefined) ??
|
|
46
|
+
GITHUB_COPILOT_INDIVIDUAL_BASE_URL);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=github-copilot-endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-copilot-endpoint.js","sourceRoot":"","sources":["../../src/api/github-copilot-endpoint.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,6FAA6F;AAC7F,+FAA+F;AAE/F,MAAM,CAAC,MAAM,kCAAkC,GAAG,0CAA0C,CAAC;AAO7F,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAE,GAAW;IACjE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;IACtG,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAa;IAC1D,MAAM,SAAS,GAAG,uBAAuB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC7D,OAAO,SAAS,CAAC,CAAC,CAAC,WAAW,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAc;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QACjG,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAiB,EAAE,KAAyB;IACrE,IAAI,CAAC,KAAK,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAClF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,6BAA6B,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IACxE,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACnG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAI3C;IACA,OAAO,CACN,gBAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC;QAChD,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,6BAA6B,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,uBAAuB,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,kCAAkC,CAClC,CAAC;AACH,CAAC","sourcesContent":["// The Copilot API host is per account plan (individual, business, enterprise, data-residency\n// tenants). A request sent to another plan's host is refused with `421 Misdirected Request`,\n// so the host always comes from the account's own token; the individual host is a last resort.\n\nexport const GITHUB_COPILOT_INDIVIDUAL_BASE_URL = \"https://api.individual.githubcopilot.com\";\n\nexport interface GitHubCopilotApiEndpoint {\n\treadonly tid: string;\n\treadonly url: string;\n}\n\nexport function githubCopilotTokenField(token: string, key: string): string | undefined {\n\tfor (const part of token.split(\";\")) {\n\t\tconst separator = part.indexOf(\"=\");\n\t\tif (separator > 0 && part.slice(0, separator) === key) return part.slice(separator + 1) || undefined;\n\t}\n\treturn undefined;\n}\n\nexport function githubCopilotBaseUrlFromToken(token: string): string | undefined {\n\tconst proxyHost = githubCopilotTokenField(token, \"proxy-ep\");\n\treturn proxyHost ? `https://${proxyHost.replace(/^proxy\\./, \"api.\")}` : undefined;\n}\n\nexport function parseGitHubCopilotApiEndpoint(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\ttry {\n\t\tconst url = new URL(value.trim());\n\t\tif (url.protocol !== \"https:\" || !url.hostname || url.username || url.password) return undefined;\n\t\treturn `${url.origin}${url.pathname.replace(/\\/+$/, \"\")}`;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction endpointForToken(endpoint: unknown, token: string | undefined): string | undefined {\n\tif (!token || typeof endpoint !== \"object\" || endpoint === null) return undefined;\n\tconst tid = Reflect.get(endpoint, \"tid\");\n\tconst url = parseGitHubCopilotApiEndpoint(Reflect.get(endpoint, \"url\"));\n\treturn typeof tid === \"string\" && tid === githubCopilotTokenField(token, \"tid\") ? url : undefined;\n}\n\n/**\n * The account's Copilot API base URL, in order: the token response's `endpoints.api` recorded for\n * this exact token (matched by `tid`, so a pooled sibling account never borrows it), the token's\n * `proxy-ep`, the GitHub Enterprise Server domain, then the individual host.\n */\nexport function resolveGitHubCopilotBaseUrl(input: {\n\ttoken?: string;\n\tapiEndpoint?: unknown;\n\tenterpriseDomain?: string;\n}): string {\n\treturn (\n\t\tendpointForToken(input.apiEndpoint, input.token) ??\n\t\t(input.token ? githubCopilotBaseUrlFromToken(input.token) : undefined) ??\n\t\t(input.enterpriseDomain ? `https://copilot-api.${input.enterpriseDomain}` : undefined) ??\n\t\tGITHUB_COPILOT_INDIVIDUAL_BASE_URL\n\t);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-copilot-errors.d.ts","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"AA0CA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"github-copilot-errors.d.ts","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"AA0CA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAkB/E;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAItG"}
|
|
@@ -60,6 +60,9 @@ export function describeGitHubCopilotFailure(error) {
|
|
|
60
60
|
if (isQuotaFailure(status, body, headerValue(headers, "x-ratelimit-exceeded"))) {
|
|
61
61
|
return `GitHub Copilot quota exceeded (HTTP ${status}): the plan's included usage or its additional-usage limit is used up, so premium models are refused until it resets or the limit is raised. Usage is shown at https://github.com/settings/copilot.${reference}`;
|
|
62
62
|
}
|
|
63
|
+
if (status === 421) {
|
|
64
|
+
return `GitHub Copilot sent this account to a different API host (HTTP 421 Misdirected Request): Business and Enterprise accounts are served from their own host, which senpi reads from the Copilot token. Run /login github-copilot so senpi stores the account's endpoint, and report it with the GitHub request id if it persists.${reference}`;
|
|
65
|
+
}
|
|
63
66
|
if (status === 403) {
|
|
64
67
|
const reason = body === undefined ? " with an empty body" : "";
|
|
65
68
|
return `GitHub Copilot refused the request (HTTP 403${reason}). Copilot checks access per model and per client; if a fresh /login github-copilot does not help, report it with the GitHub request id.${reference}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-copilot-errors.js","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeProviderError } from \"../utils/error-body.ts\";\nimport { formatProviderRequestId } from \"../utils/retry.ts\";\n\n// Codes VS Code Copilot Chat treats as quota exhaustion (extensions/copilot chatMLFetcher.ts).\nconst QUOTA_CODES = new Set([\n\t\"quota_exceeded\",\n\t\"free_quota_exceeded\",\n\t\"overage_limit_reached\",\n\t\"billing_not_configured\",\n\t\"additional_spend_limit_reached\",\n]);\n\nfunction headerValue(headers: unknown, name: string): string | undefined {\n\tif (headers instanceof Headers) return headers.get(name) ?? undefined;\n\tif (typeof headers !== \"object\" || headers === null) return undefined;\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === name && typeof value === \"string\") return value;\n\t}\n\treturn undefined;\n}\n\nfunction errorCode(body: string | undefined): string | undefined {\n\tif (body === undefined) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\tif (typeof parsed !== \"object\" || parsed === null) return undefined;\n\t\tconst nested = Reflect.get(parsed, \"error\");\n\t\tconst code =\n\t\t\ttypeof nested === \"object\" && nested !== null ? Reflect.get(nested, \"code\") : Reflect.get(parsed, \"code\");\n\t\treturn typeof code === \"string\" ? code : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isQuotaFailure(status: number, body: string | undefined, limitKey: string | undefined): boolean {\n\tconst code = errorCode(body);\n\tif (code !== undefined && QUOTA_CODES.has(code)) return true;\n\tif (status === 402) return true;\n\treturn status === 429 && (limitKey?.includes(\"quota\") === true || /quota exceeded/i.test(body ?? \"\"));\n}\n\n/**\n * A plain-language note for a GitHub Copilot HTTP failure that the SDK message alone\n * leaves opaque (`403 status code (no body)`): which refusal it is, where to look, and\n * the GitHub request id support needs. `undefined` for failures the message already\n * explains. The wording avoids credential words so pool classification is unchanged.\n */\nexport function describeGitHubCopilotFailure(error: unknown): string | undefined {\n\tif (!(error instanceof Error)) return undefined;\n\tconst { status, body } = normalizeProviderError(error);\n\tif (status === undefined) return undefined;\n\tconst headers = Reflect.get(error, \"headers\");\n\tconst requestId = headerValue(headers, \"x-github-request-id\");\n\tconst reference = requestId === undefined ? \"\" : ` ${formatProviderRequestId(\"GitHub\", requestId)}.`;\n\tif (isQuotaFailure(status, body, headerValue(headers, \"x-ratelimit-exceeded\"))) {\n\t\treturn `GitHub Copilot quota exceeded (HTTP ${status}): the plan's included usage or its additional-usage limit is used up, so premium models are refused until it resets or the limit is raised. Usage is shown at https://github.com/settings/copilot.${reference}`;\n\t}\n\tif (status === 403) {\n\t\tconst reason = body === undefined ? \" with an empty body\" : \"\";\n\t\treturn `GitHub Copilot refused the request (HTTP 403${reason}). Copilot checks access per model and per client; if a fresh /login github-copilot does not help, report it with the GitHub request id.${reference}`;\n\t}\n\treturn undefined;\n}\n\nexport function withGitHubCopilotFailureNote(message: string, provider: string, error: unknown): string {\n\tif (provider !== \"github-copilot\") return message;\n\tconst note = describeGitHubCopilotFailure(error);\n\treturn note === undefined ? message : `${message}\\n${note}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"github-copilot-errors.js","sourceRoot":"","sources":["../../src/api/github-copilot-errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { normalizeProviderError } from \"../utils/error-body.ts\";\nimport { formatProviderRequestId } from \"../utils/retry.ts\";\n\n// Codes VS Code Copilot Chat treats as quota exhaustion (extensions/copilot chatMLFetcher.ts).\nconst QUOTA_CODES = new Set([\n\t\"quota_exceeded\",\n\t\"free_quota_exceeded\",\n\t\"overage_limit_reached\",\n\t\"billing_not_configured\",\n\t\"additional_spend_limit_reached\",\n]);\n\nfunction headerValue(headers: unknown, name: string): string | undefined {\n\tif (headers instanceof Headers) return headers.get(name) ?? undefined;\n\tif (typeof headers !== \"object\" || headers === null) return undefined;\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (key.toLowerCase() === name && typeof value === \"string\") return value;\n\t}\n\treturn undefined;\n}\n\nfunction errorCode(body: string | undefined): string | undefined {\n\tif (body === undefined) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\tif (typeof parsed !== \"object\" || parsed === null) return undefined;\n\t\tconst nested = Reflect.get(parsed, \"error\");\n\t\tconst code =\n\t\t\ttypeof nested === \"object\" && nested !== null ? Reflect.get(nested, \"code\") : Reflect.get(parsed, \"code\");\n\t\treturn typeof code === \"string\" ? code : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isQuotaFailure(status: number, body: string | undefined, limitKey: string | undefined): boolean {\n\tconst code = errorCode(body);\n\tif (code !== undefined && QUOTA_CODES.has(code)) return true;\n\tif (status === 402) return true;\n\treturn status === 429 && (limitKey?.includes(\"quota\") === true || /quota exceeded/i.test(body ?? \"\"));\n}\n\n/**\n * A plain-language note for a GitHub Copilot HTTP failure that the SDK message alone\n * leaves opaque (`403 status code (no body)`): which refusal it is, where to look, and\n * the GitHub request id support needs. `undefined` for failures the message already\n * explains. The wording avoids credential words so pool classification is unchanged.\n */\nexport function describeGitHubCopilotFailure(error: unknown): string | undefined {\n\tif (!(error instanceof Error)) return undefined;\n\tconst { status, body } = normalizeProviderError(error);\n\tif (status === undefined) return undefined;\n\tconst headers = Reflect.get(error, \"headers\");\n\tconst requestId = headerValue(headers, \"x-github-request-id\");\n\tconst reference = requestId === undefined ? \"\" : ` ${formatProviderRequestId(\"GitHub\", requestId)}.`;\n\tif (isQuotaFailure(status, body, headerValue(headers, \"x-ratelimit-exceeded\"))) {\n\t\treturn `GitHub Copilot quota exceeded (HTTP ${status}): the plan's included usage or its additional-usage limit is used up, so premium models are refused until it resets or the limit is raised. Usage is shown at https://github.com/settings/copilot.${reference}`;\n\t}\n\tif (status === 421) {\n\t\treturn `GitHub Copilot sent this account to a different API host (HTTP 421 Misdirected Request): Business and Enterprise accounts are served from their own host, which senpi reads from the Copilot token. Run /login github-copilot so senpi stores the account's endpoint, and report it with the GitHub request id if it persists.${reference}`;\n\t}\n\tif (status === 403) {\n\t\tconst reason = body === undefined ? \" with an empty body\" : \"\";\n\t\treturn `GitHub Copilot refused the request (HTTP 403${reason}). Copilot checks access per model and per client; if a fresh /login github-copilot does not help, report it with the GitHub request id.${reference}`;\n\t}\n\treturn undefined;\n}\n\nexport function withGitHubCopilotFailureNote(message: string, provider: string, error: unknown): string {\n\tif (provider !== \"github-copilot\") return message;\n\tconst note = describeGitHubCopilotFailure(error);\n\treturn note === undefined ? message : `${message}\\n${note}`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"github-copilot.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,SAAS,EAA4C,MAAM,aAAa,CAAC;AAubvF,eAAO,MAAM,kBAAkB,EAAE,SAmBhC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GitHub Copilot OAuth flow
|
|
3
3
|
*/
|
|
4
|
+
import { GITHUB_COPILOT_INDIVIDUAL_BASE_URL, githubCopilotTokenField, parseGitHubCopilotApiEndpoint, resolveGitHubCopilotBaseUrl, } from "../../api/github-copilot-endpoint.js";
|
|
4
5
|
import { GITHUB_COPILOT_REJECTED_TOKEN_STATUSES } from "../../api/github-copilot-headers.js";
|
|
5
6
|
import { sleep } from "../../utils/sleep.js";
|
|
6
7
|
import { pollOAuthDeviceCodeFlow } from "./device-code.js";
|
|
@@ -33,31 +34,8 @@ function getUrls(domain) {
|
|
|
33
34
|
copilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...
|
|
39
|
-
* Returns API URL like https://api.individual.githubcopilot.com
|
|
40
|
-
*/
|
|
41
|
-
function getBaseUrlFromToken(token) {
|
|
42
|
-
const match = token.match(/proxy-ep=([^;]+)/);
|
|
43
|
-
if (!match)
|
|
44
|
-
return null;
|
|
45
|
-
const proxyHost = match[1];
|
|
46
|
-
// Convert proxy.xxx to api.xxx
|
|
47
|
-
const apiHost = proxyHost.replace(/^proxy\./, "api.");
|
|
48
|
-
return `https://${apiHost}`;
|
|
49
|
-
}
|
|
50
|
-
function getGitHubCopilotBaseUrl(token, enterpriseDomain) {
|
|
51
|
-
// If we have a token, extract the base URL from proxy-ep
|
|
52
|
-
if (token) {
|
|
53
|
-
const urlFromToken = getBaseUrlFromToken(token);
|
|
54
|
-
if (urlFromToken)
|
|
55
|
-
return urlFromToken;
|
|
56
|
-
}
|
|
57
|
-
// Fallback for enterprise or if token parsing fails
|
|
58
|
-
if (enterpriseDomain)
|
|
59
|
-
return `https://copilot-api.${enterpriseDomain}`;
|
|
60
|
-
return "https://api.individual.githubcopilot.com";
|
|
37
|
+
function getGitHubCopilotBaseUrl(token, enterpriseDomain, apiEndpoint) {
|
|
38
|
+
return resolveGitHubCopilotBaseUrl({ token, enterpriseDomain, apiEndpoint });
|
|
61
39
|
}
|
|
62
40
|
async function fetchWithRateLimitRetry(url, init, signal, retryPolicy) {
|
|
63
41
|
const retryBudgetSignal = retryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0
|
|
@@ -87,11 +65,11 @@ async function fetchWithRateLimitRetry(url, init, signal, retryPolicy) {
|
|
|
87
65
|
await sleep(delayMs, requestSignal);
|
|
88
66
|
}
|
|
89
67
|
}
|
|
90
|
-
async function fetchGitHubCopilotModels(copilotToken, enterpriseDomain, signal, retryPolicy) {
|
|
91
|
-
const baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);
|
|
68
|
+
async function fetchGitHubCopilotModels(copilotToken, enterpriseDomain, signal, retryPolicy, apiEndpoint) {
|
|
69
|
+
const baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain, apiEndpoint);
|
|
92
70
|
// Some Individual accounts return false for every picker flag despite explicit enabled policies.
|
|
93
71
|
// Limit the fallback to that endpoint so other account types keep strict picker semantics.
|
|
94
|
-
const allowPolicyFallback = baseUrl ===
|
|
72
|
+
const allowPolicyFallback = baseUrl === GITHUB_COPILOT_INDIVIDUAL_BASE_URL;
|
|
95
73
|
const response = await fetchWithRateLimitRetry(`${baseUrl}/models`, {
|
|
96
74
|
headers: {
|
|
97
75
|
Accept: "application/json",
|
|
@@ -222,12 +200,16 @@ async function refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, s
|
|
|
222
200
|
if (typeof token !== "string" || typeof expiresAt !== "number") {
|
|
223
201
|
throw new Error("Invalid Copilot token response fields");
|
|
224
202
|
}
|
|
203
|
+
const endpoints = raw.endpoints;
|
|
204
|
+
const apiUrl = parseGitHubCopilotApiEndpoint(typeof endpoints === "object" && endpoints !== null ? Reflect.get(endpoints, "api") : undefined);
|
|
205
|
+
const tid = githubCopilotTokenField(token, "tid");
|
|
225
206
|
return {
|
|
226
207
|
type: "oauth",
|
|
227
208
|
refresh: refreshToken,
|
|
228
209
|
access: token,
|
|
229
210
|
expires: expiresAt * 1000 - 5 * 60 * 1000,
|
|
230
211
|
enterpriseUrl: enterpriseDomain,
|
|
212
|
+
...(apiUrl !== undefined && tid !== undefined ? { copilotApiEndpoint: { tid, url: apiUrl } } : {}),
|
|
231
213
|
};
|
|
232
214
|
}
|
|
233
215
|
/**
|
|
@@ -238,7 +220,7 @@ async function refreshGitHubCopilotToken(refreshToken, enterpriseDomain, signal)
|
|
|
238
220
|
const { availableModelIds, modelLimits } = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain, signal, {
|
|
239
221
|
maxRetries: 0,
|
|
240
222
|
maxElapsedMs: 0,
|
|
241
|
-
});
|
|
223
|
+
}, credentials.copilotApiEndpoint);
|
|
242
224
|
return {
|
|
243
225
|
...credentials,
|
|
244
226
|
availableModelIds,
|
|
@@ -249,8 +231,8 @@ async function refreshGitHubCopilotToken(refreshToken, enterpriseDomain, signal)
|
|
|
249
231
|
* Enable a model for the user's GitHub Copilot account.
|
|
250
232
|
* This is required for some models (like Claude, Grok) before they can be used.
|
|
251
233
|
*/
|
|
252
|
-
async function enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal) {
|
|
253
|
-
const baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);
|
|
234
|
+
async function enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal, apiEndpoint) {
|
|
235
|
+
const baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain, apiEndpoint);
|
|
254
236
|
const url = `${baseUrl}/models/${modelId}/policy`;
|
|
255
237
|
let response;
|
|
256
238
|
try {
|
|
@@ -280,11 +262,11 @@ async function enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal
|
|
|
280
262
|
* Enable the requested GitHub Copilot models and return the successful IDs.
|
|
281
263
|
* Policy updates are best effort; exhausted rate limiting stops the batch.
|
|
282
264
|
*/
|
|
283
|
-
async function enableGitHubCopilotModels(token, modelIds, enterpriseDomain, signal) {
|
|
265
|
+
async function enableGitHubCopilotModels(token, modelIds, enterpriseDomain, signal, apiEndpoint) {
|
|
284
266
|
const enabledModelIds = [];
|
|
285
267
|
for (const modelId of modelIds) {
|
|
286
268
|
try {
|
|
287
|
-
if (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {
|
|
269
|
+
if (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal, apiEndpoint)) {
|
|
288
270
|
enabledModelIds.push(modelId);
|
|
289
271
|
}
|
|
290
272
|
}
|
|
@@ -322,11 +304,11 @@ async function loginGitHubCopilot(interaction) {
|
|
|
322
304
|
const models = await fetchGitHubCopilotModels(credentials.access, enterpriseDomain ?? undefined, interaction.signal, {
|
|
323
305
|
maxRetries: 2,
|
|
324
306
|
maxElapsedMs: 5000,
|
|
325
|
-
});
|
|
307
|
+
}, credentials.copilotApiEndpoint);
|
|
326
308
|
let enabledModelIds = [];
|
|
327
309
|
if (models.policyModelIds.length > 0) {
|
|
328
310
|
interaction.notify({ type: "progress", message: "Enabling models..." });
|
|
329
|
-
enabledModelIds = await enableGitHubCopilotModels(credentials.access, models.policyModelIds, enterpriseDomain ?? undefined, interaction.signal);
|
|
311
|
+
enabledModelIds = await enableGitHubCopilotModels(credentials.access, models.policyModelIds, enterpriseDomain ?? undefined, interaction.signal, credentials.copilotApiEndpoint);
|
|
330
312
|
}
|
|
331
313
|
return {
|
|
332
314
|
...credentials,
|
|
@@ -350,7 +332,7 @@ export const githubCopilotOAuth = {
|
|
|
350
332
|
async toAuth(credential) {
|
|
351
333
|
return {
|
|
352
334
|
apiKey: credential.access,
|
|
353
|
-
baseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),
|
|
335
|
+
baseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential), credential.copilotApiEndpoint),
|
|
354
336
|
};
|
|
355
337
|
},
|
|
356
338
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport { GITHUB_COPILOT_REJECTED_TOKEN_STATUSES } from \"../../api/github-copilot-headers.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\nimport { parseGitHubCopilotModelCatalog } from \"./github-copilot-model-catalog.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\n/**\n * Parse the proxy-ep from a Copilot token and convert to API base URL.\n * Token format: tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...\n * Returns API URL like https://api.individual.githubcopilot.com\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n\tconst match = token.match(/proxy-ep=([^;]+)/);\n\tif (!match) return null;\n\tconst proxyHost = match[1];\n\t// Convert proxy.xxx to api.xxx\n\tconst apiHost = proxyHost.replace(/^proxy\\./, \"api.\");\n\treturn `https://${apiHost}`;\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n\t// If we have a token, extract the base URL from proxy-ep\n\tif (token) {\n\t\tconst urlFromToken = getBaseUrlFromToken(token);\n\t\tif (urlFromToken) return urlFromToken;\n\t}\n\t// Fallback for enterprise or if token parsing fails\n\tif (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n\treturn \"https://api.individual.githubcopilot.com\";\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === \"https://api.individual.githubcopilot.com\";\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds, modelLimits } = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain,\n\t\tsignal,\n\t\t{\n\t\t\tmaxRetries: 0,\n\t\t\tmaxElapsedMs: 0,\n\t\t},\n\t);\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t\tcopilotModelLimits: modelLimits,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t\tcopilotModelLimits: models.modelLimits,\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\trejectedTokenStatuses: GITHUB_COPILOT_REJECTED_TOKEN_STATUSES,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(credential.access, copilotEnterpriseDomain(credential)),\n\t\t};\n\t},\n};\n"]}
|
|
1
|
+
{"version":3,"file":"github-copilot.js","sourceRoot":"","sources":["../../../src/auth/oauth/github-copilot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GitHub Copilot OAuth flow\n */\n\nimport {\n\tGITHUB_COPILOT_INDIVIDUAL_BASE_URL,\n\tgithubCopilotTokenField,\n\tparseGitHubCopilotApiEndpoint,\n\tresolveGitHubCopilotBaseUrl,\n} from \"../../api/github-copilot-endpoint.ts\";\nimport { GITHUB_COPILOT_REJECTED_TOKEN_STATUSES } from \"../../api/github-copilot-headers.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\nimport { parseGitHubCopilotModelCatalog } from \"./github-copilot-model-catalog.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"SXYxLmI1MDdhMDhjODdlY2ZlOTg=\");\n\nconst COPILOT_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\nconst COPILOT_API_VERSION = \"2026-06-01\";\n\ntype DeviceCodeResponse = {\n\tdevice_code: string;\n\tuser_code: string;\n\tverification_uri: string;\n\tinterval?: number;\n\texpires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n\taccess_token: string;\n\ttoken_type?: string;\n\tscope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n\terror: string;\n\terror_description?: string;\n\tinterval?: number;\n};\n\nfunction normalizeDomain(input: string): string | null {\n\tconst trimmed = input.trim();\n\tif (!trimmed) return null;\n\ttry {\n\t\tconst url = trimmed.includes(\"://\") ? new URL(trimmed) : new URL(`https://${trimmed}`);\n\t\treturn url.hostname;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getUrls(domain: string): {\n\tdeviceCodeUrl: string;\n\taccessTokenUrl: string;\n\tcopilotTokenUrl: string;\n} {\n\treturn {\n\t\tdeviceCodeUrl: `https://${domain}/login/device/code`,\n\t\taccessTokenUrl: `https://${domain}/login/oauth/access_token`,\n\t\tcopilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n\t};\n}\n\nfunction getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string, apiEndpoint?: unknown): string {\n\treturn resolveGitHubCopilotBaseUrl({ token, enterpriseDomain, apiEndpoint });\n}\n\nasync function fetchWithRateLimitRetry(\n\turl: string,\n\tinit: RequestInit,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n): Promise<Response> {\n\tconst retryBudgetSignal =\n\t\tretryPolicy.maxRetries > 0 && retryPolicy.maxElapsedMs > 0\n\t\t\t? AbortSignal.timeout(retryPolicy.maxElapsedMs)\n\t\t\t: undefined;\n\tconst requestSignal = retryBudgetSignal ? AbortSignal.any([signal, retryBudgetSignal]) : signal;\n\tconst retryDeadline = retryBudgetSignal ? Date.now() + retryPolicy.maxElapsedMs : undefined;\n\tfor (let retry = 0; ; retry++) {\n\t\tconst response = await fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: AbortSignal.any([requestSignal, AbortSignal.timeout(5000)]),\n\t\t});\n\t\tif (response.status !== 429 || retry === retryPolicy.maxRetries) return response;\n\n\t\tconst retryAfter = response.headers.get(\"retry-after\");\n\t\tlet delayMs = 500 * 2 ** retry;\n\t\tif (retryAfter) {\n\t\t\tconst seconds = Number.parseFloat(retryAfter);\n\t\t\tdelayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n\t\t\tif (!Number.isFinite(delayMs)) return response;\n\t\t}\n\t\tdelayMs = Math.max(0, delayMs);\n\t\tif (retryDeadline !== undefined && delayMs >= retryDeadline - Date.now()) return response;\n\t\tawait response.body?.cancel();\n\t\tawait sleep(delayMs, requestSignal);\n\t}\n}\n\nasync function fetchGitHubCopilotModels(\n\tcopilotToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tretryPolicy: { maxRetries: number; maxElapsedMs: number },\n\tapiEndpoint?: unknown,\n) {\n\tconst baseUrl = getGitHubCopilotBaseUrl(copilotToken, enterpriseDomain, apiEndpoint);\n\t// Some Individual accounts return false for every picker flag despite explicit enabled policies.\n\t// Limit the fallback to that endpoint so other account types keep strict picker semantics.\n\tconst allowPolicyFallback = baseUrl === GITHUB_COPILOT_INDIVIDUAL_BASE_URL;\n\tconst response = await fetchWithRateLimitRetry(\n\t\t`${baseUrl}/models`,\n\t\t{\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${copilotToken}`,\n\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\"X-GitHub-Api-Version\": COPILOT_API_VERSION,\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t\tretryPolicy,\n\t);\n\tif (!response.ok) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn parseGitHubCopilotModelCatalog(await response.json(), allowPolicyFallback);\n}\n\nasync function fetchJson(url: string, init: RequestInit): Promise<unknown> {\n\tconst response = await fetch(url, init);\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${text}`);\n\t}\n\treturn response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal: AbortSignal): Promise<DeviceCodeResponse> {\n\tconst urls = getUrls(domain);\n\tconst data = await fetchJson(urls.deviceCodeUrl, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tscope: \"read:user\",\n\t\t}),\n\t\tsignal,\n\t});\n\n\tif (!data || typeof data !== \"object\") {\n\t\tthrow new Error(\"Invalid device code response\");\n\t}\n\n\tconst deviceCode = (data as Record<string, unknown>).device_code;\n\tconst userCode = (data as Record<string, unknown>).user_code;\n\tconst verificationUri = (data as Record<string, unknown>).verification_uri;\n\tconst interval = (data as Record<string, unknown>).interval;\n\tconst expiresIn = (data as Record<string, unknown>).expires_in;\n\n\tif (\n\t\ttypeof deviceCode !== \"string\" ||\n\t\ttypeof userCode !== \"string\" ||\n\t\ttypeof verificationUri !== \"string\" ||\n\t\t(interval !== undefined && typeof interval !== \"number\") ||\n\t\ttypeof expiresIn !== \"number\"\n\t) {\n\t\tthrow new Error(\"Invalid device code response fields\");\n\t}\n\n\t// The verification URI is opened in the user's browser and to prevent `open` from\n\t// opening an executable or similar, we force it to be a URL.\n\tlet parsedUri: URL;\n\ttry {\n\t\tparsedUri = new URL(verificationUri);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\tif (parsedUri.protocol !== \"https:\" && parsedUri.protocol !== \"http:\") {\n\t\tthrow new Error(\"Untrusted verification_uri in device code response\");\n\t}\n\n\treturn {\n\t\tdevice_code: deviceCode,\n\t\tuser_code: userCode,\n\t\tverification_uri: parsedUri.href,\n\t\tinterval,\n\t\texpires_in: expiresIn,\n\t};\n}\n\nasync function pollForGitHubAccessToken(\n\tdomain: string,\n\tdevice: DeviceCodeResponse,\n\tsignal: AbortSignal,\n): Promise<string> {\n\tconst urls = getUrls(domain);\n\treturn pollOAuthDeviceCodeFlow<string>({\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst raw = await fetchJson(urls.accessTokenUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t},\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\t\tdevice_code: device.device_code,\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t}),\n\t\t\t\tsignal,\n\t\t\t});\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenSuccessResponse).access_token === \"string\") {\n\t\t\t\treturn { status: \"complete\", value: (raw as DeviceTokenSuccessResponse).access_token };\n\t\t\t}\n\n\t\t\tif (raw && typeof raw === \"object\" && typeof (raw as DeviceTokenErrorResponse).error === \"string\") {\n\t\t\t\tconst { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n\t\t\t\tif (error === \"authorization_pending\") {\n\t\t\t\t\treturn { status: \"pending\" };\n\t\t\t\t}\n\n\t\t\t\tif (error === \"slow_down\") {\n\t\t\t\t\treturn { status: \"slow_down\", intervalSeconds: typeof interval === \"number\" ? interval : undefined };\n\t\t\t\t}\n\n\t\t\t\tconst descriptionSuffix = description ? `: ${description}` : \"\";\n\t\t\t\treturn { status: \"failed\", message: `Device flow failed: ${error}${descriptionSuffix}` };\n\t\t\t}\n\n\t\t\treturn { status: \"failed\", message: \"Invalid device token response\" };\n\t\t},\n\t});\n}\n\nasync function refreshGitHubCopilotAccessToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst domain = enterpriseDomain || \"github.com\";\n\tconst urls = getUrls(domain);\n\n\tconst raw = await fetchJson(urls.copilotTokenUrl, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t\tAuthorization: `Bearer ${refreshToken}`,\n\t\t\t...COPILOT_HEADERS,\n\t\t},\n\t\tsignal,\n\t});\n\n\tif (!raw || typeof raw !== \"object\") {\n\t\tthrow new Error(\"Invalid Copilot token response\");\n\t}\n\n\tconst token = (raw as Record<string, unknown>).token;\n\tconst expiresAt = (raw as Record<string, unknown>).expires_at;\n\n\tif (typeof token !== \"string\" || typeof expiresAt !== \"number\") {\n\t\tthrow new Error(\"Invalid Copilot token response fields\");\n\t}\n\n\tconst endpoints = (raw as Record<string, unknown>).endpoints;\n\tconst apiUrl = parseGitHubCopilotApiEndpoint(\n\t\ttypeof endpoints === \"object\" && endpoints !== null ? Reflect.get(endpoints, \"api\") : undefined,\n\t);\n\tconst tid = githubCopilotTokenField(token, \"tid\");\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: refreshToken,\n\t\taccess: token,\n\t\texpires: expiresAt * 1000 - 5 * 60 * 1000,\n\t\tenterpriseUrl: enterpriseDomain,\n\t\t...(apiUrl !== undefined && tid !== undefined ? { copilotApiEndpoint: { tid, url: apiUrl } } : {}),\n\t};\n}\n\n/**\n * Refresh GitHub Copilot token\n */\nasync function refreshGitHubCopilotToken(\n\trefreshToken: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tconst credentials = await refreshGitHubCopilotAccessToken(refreshToken, enterpriseDomain, signal);\n\tconst { availableModelIds, modelLimits } = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain,\n\t\tsignal,\n\t\t{\n\t\t\tmaxRetries: 0,\n\t\t\tmaxElapsedMs: 0,\n\t\t},\n\t\tcredentials.copilotApiEndpoint,\n\t);\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds,\n\t\tcopilotModelLimits: modelLimits,\n\t};\n}\n\n/**\n * Enable a model for the user's GitHub Copilot account.\n * This is required for some models (like Claude, Grok) before they can be used.\n */\nasync function enableGitHubCopilotModel(\n\ttoken: string,\n\tmodelId: string,\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tapiEndpoint?: unknown,\n): Promise<boolean> {\n\tconst baseUrl = getGitHubCopilotBaseUrl(token, enterpriseDomain, apiEndpoint);\n\tconst url = `${baseUrl}/models/${modelId}/policy`;\n\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchWithRateLimitRetry(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...COPILOT_HEADERS,\n\t\t\t\t\t\"openai-intent\": \"chat-policy\",\n\t\t\t\t\t\"x-interaction-type\": \"chat-policy\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ state: \"enabled\" }),\n\t\t\t},\n\t\t\tsignal,\n\t\t\t{ maxRetries: 2, maxElapsedMs: 5000 },\n\t\t);\n\t} catch (error) {\n\t\tif (signal.aborted) throw error;\n\t\treturn false;\n\t}\n\tif (response.status === 429) {\n\t\tthrow new Error(`${response.status} ${response.statusText}: ${await response.text()}`);\n\t}\n\treturn response.ok;\n}\n\n/**\n * Enable the requested GitHub Copilot models and return the successful IDs.\n * Policy updates are best effort; exhausted rate limiting stops the batch.\n */\nasync function enableGitHubCopilotModels(\n\ttoken: string,\n\tmodelIds: readonly string[],\n\tenterpriseDomain: string | undefined,\n\tsignal: AbortSignal,\n\tapiEndpoint?: unknown,\n): Promise<string[]> {\n\tconst enabledModelIds: string[] = [];\n\tfor (const modelId of modelIds) {\n\t\ttry {\n\t\t\tif (await enableGitHubCopilotModel(token, modelId, enterpriseDomain, signal, apiEndpoint)) {\n\t\t\t\tenabledModelIds.push(modelId);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw error;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn enabledModelIds;\n}\n\nasync function loginGitHubCopilot(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst input = await interaction.prompt({\n\t\ttype: \"text\",\n\t\tmessage: \"GitHub Enterprise URL/domain (blank for github.com)\",\n\t\tplaceholder: \"company.ghe.com\",\n\t});\n\tif (interaction.signal.aborted) throw new Error(\"Login cancelled\");\n\n\tconst trimmed = input.trim();\n\tconst enterpriseDomain = normalizeDomain(input);\n\tif (trimmed && !enterpriseDomain) throw new Error(\"Invalid GitHub Enterprise URL/domain\");\n\tconst domain = enterpriseDomain || \"github.com\";\n\n\tconst device = await startDeviceFlow(domain, interaction.signal);\n\tinteraction.notify({\n\t\ttype: \"device_code\",\n\t\tuserCode: device.user_code,\n\t\tverificationUri: device.verification_uri,\n\t\tintervalSeconds: device.interval,\n\t\texpiresInSeconds: device.expires_in,\n\t});\n\n\tconst githubAccessToken = await pollForGitHubAccessToken(domain, device, interaction.signal);\n\tconst credentials = await refreshGitHubCopilotAccessToken(\n\t\tgithubAccessToken,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t);\n\tconst models = await fetchGitHubCopilotModels(\n\t\tcredentials.access,\n\t\tenterpriseDomain ?? undefined,\n\t\tinteraction.signal,\n\t\t{\n\t\t\tmaxRetries: 2,\n\t\t\tmaxElapsedMs: 5000,\n\t\t},\n\t\tcredentials.copilotApiEndpoint,\n\t);\n\tlet enabledModelIds: string[] = [];\n\tif (models.policyModelIds.length > 0) {\n\t\tinteraction.notify({ type: \"progress\", message: \"Enabling models...\" });\n\t\tenabledModelIds = await enableGitHubCopilotModels(\n\t\t\tcredentials.access,\n\t\t\tmodels.policyModelIds,\n\t\t\tenterpriseDomain ?? undefined,\n\t\t\tinteraction.signal,\n\t\t\tcredentials.copilotApiEndpoint,\n\t\t);\n\t}\n\treturn {\n\t\t...credentials,\n\t\tavailableModelIds: [...new Set([...models.availableModelIds, ...enabledModelIds])],\n\t\tcopilotModelLimits: models.modelLimits,\n\t};\n}\n\nfunction copilotEnterpriseDomain(credential: OAuthCredential): string | undefined {\n\tconst enterpriseUrl = credential.enterpriseUrl;\n\tif (typeof enterpriseUrl !== \"string\" || !enterpriseUrl) return undefined;\n\treturn normalizeDomain(enterpriseUrl) ?? undefined;\n}\n\nexport const githubCopilotOAuth: OAuthAuth = {\n\tname: \"GitHub Copilot\",\n\tisSubscription: true,\n\trejectedTokenStatuses: GITHUB_COPILOT_REJECTED_TOKEN_STATUSES,\n\tlogin: loginGitHubCopilot,\n\trefresh: (credential, signal) =>\n\t\trefreshGitHubCopilotToken(credential.refresh, copilotEnterpriseDomain(credential), signal),\n\n\t/** Derive the credential-specific proxy endpoint for each request. */\n\tasync toAuth(credential) {\n\t\treturn {\n\t\t\tapiKey: credential.access,\n\t\t\tbaseUrl: getGitHubCopilotBaseUrl(\n\t\t\t\tcredential.access,\n\t\t\t\tcopilotEnterpriseDomain(credential),\n\t\t\t\tcredential.copilotApiEndpoint,\n\t\t\t),\n\t\t};\n\t},\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":3,"generatedAt":"2026-09-
|
|
1
|
+
{"schemaVersion":3,"generatedAt":"2026-09-28T16:29:00.961Z","structureHash":"0f74a0e81adba82c740a44aa474034c75cbb7ce24941c535c72cd6f3902a0d5d","files":{"alibaba-token-plan.json":"3a9c1be76d47459371e9fa2feeffc31e7edbbfec65fa9cc41236988efc4cf6d9","amazon-bedrock.json":"848e38fd1ade9c6e94c3037c1c6104ac515809a6f190d264eafd9f48ab0ae1ae","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"f9db437d92449fb860a2d457a6019cdfd51c11180c08df2b5f14d75ade773953","azure-openai-responses.json":"d97b98b63595dd30c138a5bcba724017f5c09c489b56be254828a298cfa087e1","bai.json":"2b12b15bd43462e60711944dd7283db8676611d9d76c82c2a01f64913e16a67e","baseten.json":"d155c434294b5167244cffb6dea6793f9669e91e8ab65b564f9510d81b330e37","cerebras.json":"3be228c613905c215c9da3d0b3535e10cc594ff2351b05390744c7c34de89b6c","chatgpt-subscription.json":"421c6ad932de4259c8f0c08589da278bed99ec80c042f2490d8ffd2a86f4da99","cloudflare-ai-gateway.json":"b64cc5c7c0df4bfce0c3c2b14fe5290636553914b09718634668ad98276a9bc5","cloudflare-workers-ai.json":"8ee15540a01cf79d0e4063c493ae3c436af2fc1d456f9faf1b066418247183e9","deepseek.json":"b5f9693ec641e9a957dc5f7a22042b3bb928bac3d7268406619b6f18e21c4b83","fireworks.json":"bbb8149854a2658f221afa47ae8e2617e6b58a8e2784aa822faaf54f0c0f18c3","github-copilot.json":"5c9fc5b1b553a26aa7bc843a3e36fa14cf220d528ecd89528c601c5090c88a2d","google-vertex.json":"97d80ac909d256cc1bf19ac54d9d8131c492e7c0c102ad89f68ade528544e0ad","google.json":"68f6cf6283cc0d69b77b0fa79e9c94774e96524f61ebba616319f05d5c9db56c","groq.json":"e4728fd72e358cd8f25e9a518e9b49a521ef44523d3debe38a7db9e0663c4077","huggingface.json":"2f93082144a7b2a1cbf79148244ce7559e0428d6310c5eb0648bca89b15a8b4b","minimax-cn.json":"4f636b47b28a507ad33b5eaba33fc4889e5956504d10f2a0d9c61167ae01ff1d","minimax.json":"9fd1764ffeefebded8579039cf0c48854a43e4c5b724f62361fc2ac54f705aa1","mistral.json":"be522597b22bceeb0bb9a0ba1781647649ffd19637d0c8e67b056d7b0ec33d52","moonshotai-cn.json":"326de79b46f6fdbf0879f005b3040d1b14049e81fa678de407b73ed1bd3bce9c","moonshotai.json":"4b917a375e9c880b903927cf5fe1ae1052c74b64d5027a007bb1e67ad0410755","nvidia.json":"6493e09b5db8b8fe9c8fae5bc15dc287645f37f83a4ed3a1ad1181e5830b5ff7","openai.json":"1856254ecf9b016193c34c9081e2fd87b95bfb837d9ee6dbf6c0e30c94044fd5","opencode-go.json":"d8bb59f10e2ba10fe6f1e36828fecbbfd92804352e89f28506ee468e69657f78","opencode.json":"1655e248e76f919fd14ca4b8a6201d1dd89b2190b295028c5d7a4a2a03809946","opengateway.json":"4f5254d6c51f1f2fc6ec05133b19db4429908b10a16a9122cdf6528067e2a8ac","openrouter.json":"2eccfd9b5af3d54ca737c8fb28f06deac8937bd1bd7a65d7bedad2c2faa66e63","qwen-token-plan-cn.json":"4bf520ed38e5c3045680d2ec2816fa8a69079dbe97f7b929767a63172288da6b","qwen-token-plan-individual.json":"eb040e78595853e980011308b1bf9caacae6dc8a91abbac5ffebd402515dd2a6","qwen-token-plan.json":"a5c67213745329ec3ba79f712f31c1c32a781d7ffb8c04f9819f36c27672531f","together.json":"200fa2cc0b4666e3818c260e41b9925b925180e2d0931d7c900e16494b2314b4","venice.json":"d34b566ee6e7a2ed31abd9099a1c0448f1d521fc696382d03d86c90634270cf1","vercel-ai-gateway.json":"95a697cd6f9eba46972dbfa301e80f18f45c701e6068c0326d2f36da10b7ce7e","xai.json":"9b23faa5218e966a17108c05d2498a617ade1eae9b0d0684284c77d67949a3f1","xiaomi-token-plan-ams.json":"7df74a255259fc1d5be8e682c3ffb0908eaaf0af711f6433dedcf345ce3e8393","xiaomi-token-plan-cn.json":"7dc672723d5b37e5b92605752f74f46f44eba10be2b0cb959790260b9e0c2a4e","xiaomi-token-plan-sgp.json":"69b333b158be038459a511a673f4536a5b03d4931c3119339f1ac741bc03d502","xiaomi.json":"333299657f211ad9edac0f3d4298b7e5776626914c9c80e22305a87533f23966","zai-coding-cn.json":"69c572aa75104f16ccbddbaace60c267f4bcc74f86d34891ca43110d312fb1ad","zai.json":"15c8182a88e58bdc1b1c3eb0603c690475342c8a826ceddfe9af1b36b28345ee"}}
|