github-copilot-oauth 1.0.0 → 1.0.1

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/index.js CHANGED
@@ -1,30 +1,544 @@
1
- import {
2
- COPILOT_HEADERS,
3
- DEFAULT_GITHUB_COPILOT_CLIENT_ID,
4
- GitHubCopilotOAuthError,
5
- copilotBase,
6
- copilotHeaders,
7
- copilotModelHeaders,
8
- copilotTokenExchangeHeaders,
9
- copilotTokenExchangeUrl,
10
- createGitHubCopilotClient,
11
- createGitHubCopilotOAuthFetch,
12
- createMemoryTokenStore,
13
- exchangeGitHubCopilotToken,
14
- githubOAuthUrls,
15
- hasVisionInput,
16
- isCopilotResponsesModel,
17
- normalizeEnterpriseDomain,
18
- startGitHubCopilotDeviceFlow
19
- } from "./chunk-CUD4IYWR.js";
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ COPILOT_HEADERS: () => COPILOT_HEADERS,
24
+ DEFAULT_GITHUB_COPILOT_CLIENT_ID: () => DEFAULT_GITHUB_COPILOT_CLIENT_ID,
25
+ GitHubCopilotOAuthError: () => GitHubCopilotOAuthError,
26
+ copilotBase: () => copilotBase,
27
+ copilotHeaders: () => copilotHeaders,
28
+ copilotModelHeaders: () => copilotModelHeaders,
29
+ copilotTokenExchangeHeaders: () => copilotTokenExchangeHeaders,
30
+ copilotTokenExchangeUrl: () => copilotTokenExchangeUrl,
31
+ createGitHubCopilot: () => createGitHubCopilot,
32
+ createGitHubCopilotClient: () => createGitHubCopilotClient,
33
+ createGitHubCopilotOAuthFetch: () => createGitHubCopilotOAuthFetch,
34
+ createMemoryTokenStore: () => createMemoryTokenStore,
35
+ exchangeGitHubCopilotToken: () => exchangeGitHubCopilotToken,
36
+ githubOAuthUrls: () => githubOAuthUrls,
37
+ hasVisionInput: () => hasVisionInput,
38
+ isCopilotResponsesModel: () => isCopilotResponsesModel,
39
+ normalizeEnterpriseDomain: () => normalizeEnterpriseDomain,
40
+ startGitHubCopilotDeviceFlow: () => startGitHubCopilotDeviceFlow
41
+ });
42
+ module.exports = __toCommonJS(index_exports);
43
+
44
+ // src/types.ts
45
+ var GitHubCopilotOAuthError = class extends Error {
46
+ code;
47
+ constructor(code, message, options) {
48
+ super(message, options);
49
+ this.name = "GitHubCopilotOAuthError";
50
+ this.code = code;
51
+ }
52
+ };
53
+
54
+ // src/enterprise.ts
55
+ function normalizeEnterpriseDomain(enterpriseUrl, options = {}) {
56
+ const value = enterpriseUrl?.trim();
57
+ if (!value) {
58
+ return void 0;
59
+ }
60
+ let parsed;
61
+ try {
62
+ parsed = new URL(/^https?:\/\//i.test(value) ? value : `https://${value}`);
63
+ } catch (error) {
64
+ throw new GitHubCopilotOAuthError("unsupported", "Invalid GitHub Enterprise URL.", { cause: error });
65
+ }
66
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
67
+ throw new GitHubCopilotOAuthError("unsupported", "Invalid GitHub Enterprise URL protocol.");
68
+ }
69
+ if (parsed.username || parsed.password || parsed.port || parsed.pathname !== "/" || parsed.search || parsed.hash) {
70
+ throw new GitHubCopilotOAuthError("unsupported", "GitHub Enterprise URL must be a hostname only.");
71
+ }
72
+ const hostname = parsed.hostname.replace(/^\[|\]$/g, "").toLowerCase();
73
+ if (!hostname || isUnsafeEnterpriseHostname(hostname)) {
74
+ throw new GitHubCopilotOAuthError("unsupported", "Unsafe GitHub Enterprise hostname.");
75
+ }
76
+ if (hostname === "github.com") {
77
+ return void 0;
78
+ }
79
+ if (!options.allowEnterprise) {
80
+ throw new GitHubCopilotOAuthError("unsupported", "Custom GitHub Enterprise hosts are not enabled.");
81
+ }
82
+ return hostname;
83
+ }
84
+ function isUnsafeEnterpriseHostname(hostname) {
85
+ return hostname === "localhost" || hostname.endsWith(".localhost") || hostname.endsWith(".local") || hostname.includes(":") || /^\d+(?:\.\d+){3}$/.test(hostname);
86
+ }
87
+ function copilotBase(enterpriseUrl, options = {}) {
88
+ const domain = normalizeEnterpriseDomain(enterpriseUrl, options);
89
+ if (!domain) {
90
+ return "https://api.githubcopilot.com";
91
+ }
92
+ return `https://copilot-api.${domain}`;
93
+ }
94
+ function copilotTokenExchangeUrl(enterpriseUrl, options = {}) {
95
+ const domain = normalizeEnterpriseDomain(enterpriseUrl, options);
96
+ if (!domain) {
97
+ return "https://api.github.com/copilot_internal/v2/token";
98
+ }
99
+ return `https://api.${domain}/copilot_internal/v2/token`;
100
+ }
101
+ function githubOAuthUrls(enterpriseUrl, options = {}) {
102
+ const domain = normalizeEnterpriseDomain(enterpriseUrl, options) ?? "github.com";
103
+ return {
104
+ domain,
105
+ code: `https://${domain}/login/device/code`,
106
+ token: `https://${domain}/login/oauth/access_token`
107
+ };
108
+ }
109
+
110
+ // src/headers.ts
111
+ var COPILOT_HEADERS = {
112
+ "User-Agent": "GitHubCopilotChat/0.35.0",
113
+ "Editor-Version": "vscode/1.107.0",
114
+ "Editor-Plugin-Version": "copilot-chat/0.35.0",
115
+ "Copilot-Integration-Id": "vscode-chat"
116
+ };
117
+ function copilotHeaders(accessToken, options) {
118
+ return {
119
+ ...COPILOT_HEADERS,
120
+ Authorization: `Bearer ${accessToken}`,
121
+ "Openai-Intent": "conversation-edits",
122
+ "X-Initiator": options?.initiator ?? "user",
123
+ ...options?.vision ? { "Copilot-Vision-Request": "true" } : {}
124
+ };
125
+ }
126
+ function copilotModelHeaders(accessToken) {
127
+ return {
128
+ ...COPILOT_HEADERS,
129
+ Authorization: `Bearer ${accessToken}`
130
+ };
131
+ }
132
+ function copilotTokenExchangeHeaders(githubToken) {
133
+ return {
134
+ Accept: "application/json",
135
+ Authorization: `Bearer ${githubToken}`,
136
+ ...COPILOT_HEADERS
137
+ };
138
+ }
139
+
140
+ // src/memory-token-store.ts
141
+ function createMemoryTokenStore(initial) {
142
+ let current = initial;
143
+ return {
144
+ async load() {
145
+ return current;
146
+ },
147
+ async save(tokens) {
148
+ current = tokens;
149
+ }
150
+ };
151
+ }
152
+
153
+ // src/token-exchange.ts
154
+ async function exchangeGitHubCopilotToken({
155
+ fetch,
156
+ githubToken,
157
+ enterpriseUrl,
158
+ allowEnterprise
159
+ }) {
160
+ const response = await fetch(copilotTokenExchangeUrl(enterpriseUrl, { allowEnterprise }), {
161
+ headers: copilotTokenExchangeHeaders(githubToken)
162
+ });
163
+ if (!response.ok) {
164
+ throw new GitHubCopilotOAuthError(
165
+ "auth_failed",
166
+ `GitHub Copilot token exchange failed (${response.status}).`
167
+ );
168
+ }
169
+ const payload = await response.json();
170
+ if (typeof payload.token !== "string" || !payload.token.trim()) {
171
+ throw new GitHubCopilotOAuthError("auth_failed", "GitHub Copilot token exchange did not return a token.");
172
+ }
173
+ if (typeof payload.expires_at !== "number" || !Number.isFinite(payload.expires_at) || payload.expires_at <= 0) {
174
+ throw new GitHubCopilotOAuthError(
175
+ "auth_failed",
176
+ "GitHub Copilot token exchange did not return a valid expiration."
177
+ );
178
+ }
179
+ return {
180
+ token: payload.token,
181
+ expiresAt: payload.expires_at * 1e3
182
+ };
183
+ }
184
+
185
+ // src/copilot-fetch.ts
186
+ var DEFAULT_REFRESH_MARGIN_MS = 60 * 1e3;
187
+ var DEFAULT_BROWSER_PROXY_BASE_URL = "/api/proxy/github-copilot";
188
+ function pickFetch(customFetch) {
189
+ if (typeof customFetch === "function") {
190
+ return customFetch;
191
+ }
192
+ if (typeof globalThis.fetch === "function") {
193
+ return globalThis.fetch.bind(globalThis);
194
+ }
195
+ throw new GitHubCopilotOAuthError("fetch_required", "A fetch implementation is required for GitHub Copilot OAuth.");
196
+ }
197
+ function withoutTrailingSlash(value) {
198
+ return value.replace(/\/$/, "");
199
+ }
200
+ function createStore(settings) {
201
+ if (settings.tokenStore) {
202
+ return settings.tokenStore;
203
+ }
204
+ if (settings.tokens) {
205
+ return createMemoryTokenStore(settings.tokens);
206
+ }
207
+ throw new GitHubCopilotOAuthError(
208
+ "tokens_required",
209
+ "GitHub Copilot OAuth tokens are required. Pass `tokens` or `tokenStore`."
210
+ );
211
+ }
212
+ var TokenManager = class {
213
+ constructor(settings, store, fetch) {
214
+ this.settings = settings;
215
+ this.store = store;
216
+ this.fetch = fetch;
217
+ }
218
+ settings;
219
+ store;
220
+ fetch;
221
+ inflight;
222
+ current;
223
+ async token() {
224
+ if (this.inflight) {
225
+ return this.inflight;
226
+ }
227
+ this.inflight = this.loadToken().finally(() => {
228
+ this.inflight = void 0;
229
+ });
230
+ return this.inflight;
231
+ }
232
+ async githubToken() {
233
+ const tokens = this.current ?? await this.store.load();
234
+ if (!tokens?.githubToken) {
235
+ throw new GitHubCopilotOAuthError("auth_failed", "GitHub Copilot OAuth token is missing.");
236
+ }
237
+ this.current = tokens;
238
+ return tokens.githubToken;
239
+ }
240
+ async loadToken() {
241
+ let tokens = this.current ?? await this.store.load();
242
+ if (!tokens?.githubToken) {
243
+ throw new GitHubCopilotOAuthError("auth_failed", "GitHub Copilot OAuth token is missing.");
244
+ }
245
+ this.current = tokens;
246
+ const margin = this.settings.tokenRefreshMarginMs ?? DEFAULT_REFRESH_MARGIN_MS;
247
+ const expiresAt = tokens.copilotTokenExpiresAt ?? 0;
248
+ if (tokens.copilotToken && (expiresAt <= 0 || expiresAt > Date.now() + margin)) {
249
+ return { token: tokens.copilotToken, fromExchange: true };
250
+ }
251
+ try {
252
+ const exchanged = await exchangeGitHubCopilotToken({
253
+ fetch: this.fetch,
254
+ githubToken: tokens.githubToken,
255
+ enterpriseUrl: this.settings.enterpriseUrl ?? tokens.enterpriseUrl,
256
+ allowEnterprise: this.settings.allowEnterprise
257
+ });
258
+ tokens = {
259
+ ...tokens,
260
+ copilotToken: exchanged.token,
261
+ copilotTokenExpiresAt: exchanged.expiresAt
262
+ };
263
+ this.current = tokens;
264
+ await this.store.save(tokens);
265
+ await this.settings.onTokens?.(tokens);
266
+ return { token: exchanged.token, fromExchange: true };
267
+ } catch (error) {
268
+ if (this.settings.fallbackToGitHubToken === false) {
269
+ throw error;
270
+ }
271
+ return { token: tokens.githubToken, fromExchange: false };
272
+ }
273
+ }
274
+ };
275
+ async function readStoredTokens(settings) {
276
+ if (settings.tokens) {
277
+ return settings.tokens;
278
+ }
279
+ const tokenStore = settings.tokenStore;
280
+ if (typeof tokenStore?.getTokens === "function") {
281
+ return tokenStore.getTokens();
282
+ }
283
+ return void 0;
284
+ }
285
+ async function resolveBaseURL(settings) {
286
+ if (settings.baseURL) {
287
+ return withoutTrailingSlash(settings.baseURL);
288
+ }
289
+ const storedTokens = await readStoredTokens(settings);
290
+ const enterpriseUrl = settings.enterpriseUrl ?? settings.tokens?.enterpriseUrl ?? storedTokens?.enterpriseUrl;
291
+ return withoutTrailingSlash(copilotBase(enterpriseUrl, settings));
292
+ }
293
+ function resolveTargetUrl(input, baseURL) {
294
+ const base = new URL(baseURL);
295
+ const parsed = /^https?:\/\//.test(input) ? new URL(input) : new URL(input, "https://copilot.invalid");
296
+ let pathname = parsed.pathname;
297
+ const basePath = withoutTrailingSlash(base.pathname);
298
+ if (basePath && pathname.startsWith(`${basePath}/`)) {
299
+ pathname = pathname.slice(basePath.length);
300
+ }
301
+ if (pathname === "/v1") {
302
+ pathname = "/";
303
+ } else if (pathname.startsWith("/v1/")) {
304
+ pathname = pathname.slice(3);
305
+ }
306
+ if (!pathname.startsWith("/")) {
307
+ pathname = `/${pathname}`;
308
+ }
309
+ return `${base.origin}${basePath}${pathname}${parsed.search}`;
310
+ }
311
+ function browserOrigin() {
312
+ const maybeWindow = globalThis.window;
313
+ return typeof maybeWindow?.location?.origin === "string" ? maybeWindow.location.origin.replace(/\/$/, "") : void 0;
314
+ }
315
+ function resolveBrowserProxyUrl(target, baseURL, settings) {
316
+ const origin = browserOrigin();
317
+ if (!origin || settings.browserProxyBaseUrl === false) {
318
+ return void 0;
319
+ }
320
+ const proxyBase = settings.browserProxyBaseUrl ?? DEFAULT_BROWSER_PROXY_BASE_URL;
321
+ const absoluteProxyBase = /^https?:\/\//.test(proxyBase) ? proxyBase.replace(/\/$/, "") : `${origin}${proxyBase.startsWith("/") ? "" : "/"}${proxyBase}`.replace(/\/$/, "");
322
+ const upstreamBasePath = withoutTrailingSlash(new URL(baseURL).pathname);
323
+ let pathname = target.pathname;
324
+ if (upstreamBasePath && pathname.startsWith(`${upstreamBasePath}/`)) {
325
+ pathname = pathname.slice(upstreamBasePath.length);
326
+ }
327
+ return `${absoluteProxyBase}${pathname}${target.search}`;
328
+ }
329
+ async function readRequestParts(input, init) {
330
+ if (input instanceof Request) {
331
+ const headers = new Headers(input.headers);
332
+ if (init?.headers) {
333
+ new Headers(init.headers).forEach((value, key) => headers.set(key, value));
334
+ }
335
+ return {
336
+ url: input.url,
337
+ method: init?.method ?? input.method,
338
+ headers,
339
+ body: init?.body ?? (input.body == null ? void 0 : await input.clone().text()),
340
+ signal: init?.signal ?? input.signal
341
+ };
342
+ }
343
+ return {
344
+ url: String(input),
345
+ method: init?.method,
346
+ headers: new Headers(init?.headers),
347
+ body: init?.body,
348
+ signal: init?.signal
349
+ };
350
+ }
351
+ async function bodyToText(body) {
352
+ if (body == null) return void 0;
353
+ if (typeof body === "string") return body;
354
+ if (body instanceof URLSearchParams) return body.toString();
355
+ if (body instanceof FormData || body instanceof ReadableStream) return void 0;
356
+ if (body instanceof Blob) return body.text();
357
+ if (body instanceof ArrayBuffer) return new TextDecoder().decode(body);
358
+ if (ArrayBuffer.isView(body)) return new TextDecoder().decode(body);
359
+ return void 0;
360
+ }
361
+ function hasVisionInput(body) {
362
+ if (!body.trim()) {
363
+ return false;
364
+ }
365
+ try {
366
+ const payload = JSON.parse(body);
367
+ const chatVision = payload.messages?.some(
368
+ (item) => Array.isArray(item.content) && item.content.some((part) => part?.type === "image_url")
369
+ );
370
+ if (chatVision) {
371
+ return true;
372
+ }
373
+ return Boolean(
374
+ payload.input?.some((item) => Array.isArray(item.content) && item.content.some((part) => part?.type === "input_image"))
375
+ );
376
+ } catch {
377
+ return false;
378
+ }
379
+ }
380
+ function applyHeaders(headers, authToken, pathname, bodyText, settings) {
381
+ const vision = settings.vision ?? (typeof bodyText === "string" && hasVisionInput(bodyText));
382
+ const authHeaders = pathname.endsWith("/models") ? copilotModelHeaders(authToken) : copilotHeaders(authToken, { vision, initiator: settings.initiator });
383
+ headers.delete("authorization");
384
+ for (const [key, value] of Object.entries(authHeaders)) {
385
+ headers.set(key, value);
386
+ }
387
+ }
388
+ function createGitHubCopilotOAuthFetch(settings = {}) {
389
+ const fetch = pickFetch(settings.fetch);
390
+ const store = createStore(settings);
391
+ const manager = new TokenManager(settings, store, fetch);
392
+ return async (input, init) => {
393
+ const baseURL = await resolveBaseURL(settings);
394
+ const request = await readRequestParts(input, init);
395
+ const targetUrl = resolveTargetUrl(request.url, baseURL);
396
+ const target = new URL(targetUrl);
397
+ const bodyText = await bodyToText(request.body);
398
+ const body = bodyText ?? request.body;
399
+ const headers = new Headers(settings.headers);
400
+ request.headers.forEach((value, key) => headers.set(key, value));
401
+ const proxyUrl = resolveBrowserProxyUrl(target, baseURL, settings);
402
+ if (proxyUrl) {
403
+ headers.delete("authorization");
404
+ headers.set("Authorization", `Bearer ${await manager.githubToken()}`);
405
+ const enterpriseUrl = settings.enterpriseUrl ?? settings.tokens?.enterpriseUrl;
406
+ if (enterpriseUrl) headers.set("x-copilot-enterprise-url", enterpriseUrl);
407
+ return fetch(proxyUrl, {
408
+ method: request.method ?? init?.method,
409
+ headers,
410
+ body,
411
+ signal: request.signal ?? void 0
412
+ });
413
+ }
414
+ const token = await manager.token();
415
+ applyHeaders(headers, token.token, target.pathname, bodyText, settings);
416
+ const response = await fetch(target.toString(), {
417
+ method: request.method ?? init?.method,
418
+ headers,
419
+ body,
420
+ signal: request.signal ?? void 0
421
+ });
422
+ if (token.fromExchange && settings.fallbackToGitHubToken !== false && (response.status === 401 || response.status === 403)) {
423
+ const fallbackHeaders = new Headers(headers);
424
+ applyHeaders(fallbackHeaders, await manager.githubToken(), target.pathname, bodyText, settings);
425
+ return fetch(target.toString(), {
426
+ method: request.method ?? init?.method,
427
+ headers: fallbackHeaders,
428
+ body,
429
+ signal: request.signal ?? void 0
430
+ });
431
+ }
432
+ return response;
433
+ };
434
+ }
435
+ async function createGitHubCopilotClient(settings = {}) {
436
+ const baseURL = await resolveBaseURL(settings);
437
+ const fetch = createGitHubCopilotOAuthFetch(settings);
438
+ return {
439
+ baseURL,
440
+ fetch,
441
+ request: (path, init) => fetch(resolveTargetUrl(path, baseURL), init)
442
+ };
443
+ }
444
+ function isCopilotResponsesModel(modelId) {
445
+ const normalized = modelId.toLowerCase();
446
+ const match = /^gpt-(\d+)/.exec(normalized);
447
+ if (!match) {
448
+ return false;
449
+ }
450
+ const generation = Number(match[1]);
451
+ return generation >= 5 && !normalized.startsWith("gpt-5-mini");
452
+ }
453
+
454
+ // src/device-flow.ts
455
+ var DEFAULT_GITHUB_COPILOT_CLIENT_ID = "Ov23li8tweQw6odWQebz";
456
+ var POLL_BUFFER_MS = 3e3;
457
+ function pickFetch2(customFetch) {
458
+ if (typeof customFetch === "function") {
459
+ return customFetch;
460
+ }
461
+ if (typeof globalThis.fetch === "function") {
462
+ return globalThis.fetch.bind(globalThis);
463
+ }
464
+ throw new GitHubCopilotOAuthError("fetch_required", "A fetch implementation is required for GitHub Copilot OAuth.");
465
+ }
466
+ async function startGitHubCopilotDeviceFlow(options = {}) {
467
+ const fetch = pickFetch2(options.fetch);
468
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
469
+ const clientId = options.clientId ?? DEFAULT_GITHUB_COPILOT_CLIENT_ID;
470
+ const urls = githubOAuthUrls(options.enterpriseUrl, { allowEnterprise: options.allowEnterprise });
471
+ const codeResponse = await fetch(urls.code, {
472
+ method: "POST",
473
+ headers: {
474
+ Accept: "application/json",
475
+ "Content-Type": "application/json"
476
+ },
477
+ body: JSON.stringify({
478
+ client_id: clientId,
479
+ scope: "read:user"
480
+ })
481
+ });
482
+ if (!codeResponse.ok) {
483
+ throw new GitHubCopilotOAuthError("auth_failed", "Failed to initiate GitHub Copilot authorization.");
484
+ }
485
+ const code = await codeResponse.json();
486
+ if (!code.verification_uri || !code.user_code || !code.device_code) {
487
+ throw new GitHubCopilotOAuthError("auth_failed", "GitHub Copilot authorization response did not include a device code.");
488
+ }
489
+ return {
490
+ providerId: "github-copilot",
491
+ url: code.verification_uri,
492
+ code: code.user_code,
493
+ instructions: `Enter code: ${code.user_code}`,
494
+ async complete() {
495
+ while (true) {
496
+ const tokenResponse = await fetch(urls.token, {
497
+ method: "POST",
498
+ headers: {
499
+ Accept: "application/json",
500
+ "Content-Type": "application/x-www-form-urlencoded"
501
+ },
502
+ body: new URLSearchParams({
503
+ client_id: clientId,
504
+ device_code: code.device_code ?? "",
505
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code"
506
+ }).toString()
507
+ });
508
+ if (!tokenResponse.ok) {
509
+ throw new GitHubCopilotOAuthError("auth_failed", "GitHub Copilot OAuth authorization failed.");
510
+ }
511
+ const token = await tokenResponse.json();
512
+ if (token.access_token) {
513
+ const result = {
514
+ githubToken: token.access_token,
515
+ ...urls.domain === "github.com" ? {} : { enterpriseUrl: urls.domain }
516
+ };
517
+ await options.tokenStore?.save(result);
518
+ return result;
519
+ }
520
+ if (token.error === "authorization_pending") {
521
+ await sleep((code.interval ?? 5) * 1e3 + POLL_BUFFER_MS);
522
+ continue;
523
+ }
524
+ if (token.error === "slow_down") {
525
+ const nextInterval = token.interval && token.interval > 0 ? token.interval : (code.interval ?? 5) + 5;
526
+ await sleep(nextInterval * 1e3 + POLL_BUFFER_MS);
527
+ continue;
528
+ }
529
+ throw new GitHubCopilotOAuthError("auth_failed", "GitHub Copilot OAuth authorization failed.");
530
+ }
531
+ }
532
+ };
533
+ }
20
534
 
21
535
  // src/provider.ts
22
- import { createOpenAI } from "@ai-sdk/openai";
23
- import { NoSuchModelError } from "@ai-sdk/provider";
536
+ var import_openai = require("@ai-sdk/openai");
537
+ var import_provider = require("@ai-sdk/provider");
24
538
  function createGitHubCopilot(settings = {}) {
25
539
  const providerName = settings.name ?? "github-copilot";
26
540
  const fetch = createGitHubCopilotOAuthFetch(settings);
27
- const openai = createOpenAI({
541
+ const openai = (0, import_openai.createOpenAI)({
28
542
  apiKey: "oauth",
29
543
  baseURL: settings.baseURL ?? copilotBase(settings.enterpriseUrl ?? settings.tokens?.enterpriseUrl, settings),
30
544
  name: providerName,
@@ -41,16 +555,17 @@ function createGitHubCopilot(settings = {}) {
41
555
  chat: createChatModel,
42
556
  responses: createResponsesModel,
43
557
  embeddingModel: (modelId) => {
44
- throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
558
+ throw new import_provider.NoSuchModelError({ modelId, modelType: "embeddingModel" });
45
559
  },
46
560
  imageModel: (modelId) => {
47
- throw new NoSuchModelError({ modelId, modelType: "imageModel" });
561
+ throw new import_provider.NoSuchModelError({ modelId, modelType: "imageModel" });
48
562
  }
49
563
  }
50
564
  );
51
565
  return provider;
52
566
  }
53
- export {
567
+ // Annotate the CommonJS export names for ESM import in node:
568
+ 0 && (module.exports = {
54
569
  COPILOT_HEADERS,
55
570
  DEFAULT_GITHUB_COPILOT_CLIENT_ID,
56
571
  GitHubCopilotOAuthError,
@@ -69,5 +584,5 @@ export {
69
584
  isCopilotResponsesModel,
70
585
  normalizeEnterpriseDomain,
71
586
  startGitHubCopilotDeviceFlow
72
- };
587
+ });
73
588
  //# sourceMappingURL=index.js.map