copilot-api-plus 1.2.17 → 1.2.19
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/README.en.md +61 -0
- package/README.md +61 -0
- package/dist/{account-manager-DmXXcFBW.js → account-manager-BLD3jHgL.js} +288 -5
- package/dist/account-manager-BLD3jHgL.js.map +1 -0
- package/dist/error-BDOdv5Up.js +2 -0
- package/dist/get-user-BSYESgez.js +2 -0
- package/dist/main.js +78 -181
- package/dist/main.js.map +1 -1
- package/dist/token-C9gxxgzi.js +3 -0
- package/dist/{token-BRQK8jBj.js → token-V-OSvQfl.js} +2 -2
- package/dist/{token-BRQK8jBj.js.map → token-V-OSvQfl.js.map} +1 -1
- package/package.json +1 -1
- package/dist/account-manager-DmXXcFBW.js.map +0 -1
- package/dist/error-Cc8bY0ph.js +0 -2
- package/dist/get-user-DHr540ak.js +0 -2
- package/dist/token-M99mSdhH.js +0 -3
package/dist/main.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { a as stopCopilotTokenRefresh, i as setupGitHubToken, n as refreshCopilotToken, o as pollAccessToken, r as setupCopilotToken, s as getDeviceCode, t as clearGithubToken } from "./token-
|
|
2
|
+
import { C as GITHUB_BASE_URL, D as standardHeaders, E as copilotHeaders, T as copilotBaseUrl, _ as findModel, a as getAccountDispatcher, b as sleep, c as notifyStreamStart, d as PATHS, f as ensurePaths, g as cacheVSCodeVersion, h as cacheModels, l as resetAccountConnections, m as forwardError, o as initProxyFromEnv, p as HTTPError, r as getCopilotUsage, s as notifyStreamEnd, t as accountManager, u as resetConnections, v as isNullish, w as GITHUB_CLIENT_ID, x as state, y as rootCause } from "./account-manager-BLD3jHgL.js";
|
|
3
|
+
import { a as stopCopilotTokenRefresh, i as setupGitHubToken, n as refreshCopilotToken, o as pollAccessToken, r as setupCopilotToken, s as getDeviceCode, t as clearGithubToken } from "./token-V-OSvQfl.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { defineCommand, runMain } from "citty";
|
|
6
6
|
import consola from "consola";
|
|
@@ -8,8 +8,6 @@ import { timingSafeEqual } from "node:crypto";
|
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import os from "node:os";
|
|
10
10
|
import path from "node:path";
|
|
11
|
-
import { getProxyForUrl } from "proxy-from-env";
|
|
12
|
-
import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
|
|
13
11
|
import * as p from "@clack/prompts";
|
|
14
12
|
import clipboard from "clipboardy";
|
|
15
13
|
import { serve } from "srvx";
|
|
@@ -119,144 +117,6 @@ async function applyProxyConfig() {
|
|
|
119
117
|
return true;
|
|
120
118
|
}
|
|
121
119
|
//#endregion
|
|
122
|
-
//#region src/lib/proxy.ts
|
|
123
|
-
const agentOptions = {
|
|
124
|
-
keepAliveTimeout: 3e5,
|
|
125
|
-
keepAliveMaxTimeout: 6e5,
|
|
126
|
-
allowH2: true,
|
|
127
|
-
connect: {
|
|
128
|
-
timeout: 15e3,
|
|
129
|
-
keepAlive: true,
|
|
130
|
-
keepAliveInitialDelay: 15e3
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
let direct;
|
|
134
|
-
let proxies = /* @__PURE__ */ new Map();
|
|
135
|
-
/** Whether a proxy is actually configured and in use. */
|
|
136
|
-
let proxyActive = false;
|
|
137
|
-
/**
|
|
138
|
-
* Many proxy nodes (especially third-party VPN/airport services) kill
|
|
139
|
-
* CONNECT tunnels that are idle for ~60 s. During long model thinking
|
|
140
|
-
* phases the SSE stream carries no data, which looks "idle" to the proxy.
|
|
141
|
-
*
|
|
142
|
-
* This keepalive sends a tiny HEAD request to the Copilot API every 45 s
|
|
143
|
-
* through the same proxy. The encrypted packets flowing through the
|
|
144
|
-
* CONNECT tunnel reset the proxy's idle timer, keeping the tunnel alive.
|
|
145
|
-
*
|
|
146
|
-
* The keepalive is active ONLY while there are SSE streams in flight
|
|
147
|
-
* (tracked via `streamCount`). When no streams are active it stops to
|
|
148
|
-
* avoid unnecessary traffic.
|
|
149
|
-
*/
|
|
150
|
-
let keepaliveTimer;
|
|
151
|
-
let streamCount = 0;
|
|
152
|
-
const KEEPALIVE_INTERVAL_MS = 45e3;
|
|
153
|
-
const KEEPALIVE_URL = "https://api.individual.githubcopilot.com/";
|
|
154
|
-
function startKeepalive() {
|
|
155
|
-
if (keepaliveTimer) return;
|
|
156
|
-
keepaliveTimer = setInterval(() => {
|
|
157
|
-
fetch(KEEPALIVE_URL, { method: "HEAD" }).catch(() => {});
|
|
158
|
-
consola.debug("Proxy keepalive ping sent");
|
|
159
|
-
}, KEEPALIVE_INTERVAL_MS);
|
|
160
|
-
keepaliveTimer.unref();
|
|
161
|
-
consola.debug("Proxy keepalive started (45 s interval)");
|
|
162
|
-
}
|
|
163
|
-
function stopKeepalive() {
|
|
164
|
-
if (keepaliveTimer) {
|
|
165
|
-
clearInterval(keepaliveTimer);
|
|
166
|
-
keepaliveTimer = void 0;
|
|
167
|
-
consola.debug("Proxy keepalive stopped (no active streams)");
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Call when an SSE stream starts. Activates the proxy-tunnel keepalive
|
|
172
|
-
* if this is the first active stream and a proxy is configured.
|
|
173
|
-
*/
|
|
174
|
-
function notifyStreamStart() {
|
|
175
|
-
if (!proxyActive) return;
|
|
176
|
-
streamCount++;
|
|
177
|
-
if (streamCount === 1) startKeepalive();
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Call when an SSE stream ends (success or error). Stops the keepalive
|
|
181
|
-
* once no streams are active.
|
|
182
|
-
*/
|
|
183
|
-
function notifyStreamEnd() {
|
|
184
|
-
if (!proxyActive) return;
|
|
185
|
-
streamCount = Math.max(0, streamCount - 1);
|
|
186
|
-
if (streamCount === 0) stopKeepalive();
|
|
187
|
-
}
|
|
188
|
-
function initProxyFromEnv() {
|
|
189
|
-
if (typeof Bun !== "undefined") return;
|
|
190
|
-
try {
|
|
191
|
-
direct = new Agent(agentOptions);
|
|
192
|
-
proxies = /* @__PURE__ */ new Map();
|
|
193
|
-
setGlobalDispatcher({
|
|
194
|
-
dispatch(options, handler) {
|
|
195
|
-
try {
|
|
196
|
-
const origin = typeof options.origin === "string" ? new URL(options.origin) : options.origin;
|
|
197
|
-
const raw = getProxyForUrl(origin.toString());
|
|
198
|
-
const proxyUrl = raw && raw.length > 0 ? raw : void 0;
|
|
199
|
-
if (!proxyUrl) {
|
|
200
|
-
consola.debug(`HTTP proxy bypass: ${origin.hostname}`);
|
|
201
|
-
return direct.dispatch(options, handler);
|
|
202
|
-
}
|
|
203
|
-
let agent = proxies.get(proxyUrl);
|
|
204
|
-
if (!agent) {
|
|
205
|
-
agent = new ProxyAgent({
|
|
206
|
-
uri: proxyUrl,
|
|
207
|
-
...agentOptions
|
|
208
|
-
});
|
|
209
|
-
proxies.set(proxyUrl, agent);
|
|
210
|
-
}
|
|
211
|
-
let label = proxyUrl;
|
|
212
|
-
try {
|
|
213
|
-
const u = new URL(proxyUrl);
|
|
214
|
-
label = `${u.protocol}//${u.host}`;
|
|
215
|
-
} catch {}
|
|
216
|
-
consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`);
|
|
217
|
-
return agent.dispatch(options, handler);
|
|
218
|
-
} catch {
|
|
219
|
-
return direct.dispatch(options, handler);
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
close() {
|
|
223
|
-
for (const agent of proxies.values()) agent.close();
|
|
224
|
-
return direct.close();
|
|
225
|
-
},
|
|
226
|
-
destroy() {
|
|
227
|
-
for (const agent of proxies.values()) agent.destroy();
|
|
228
|
-
return direct.destroy();
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
proxyActive = true;
|
|
232
|
-
consola.debug("HTTP proxy configured from environment (per-URL)");
|
|
233
|
-
} catch (err) {
|
|
234
|
-
consola.debug("Proxy setup skipped:", err);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Destroy all pooled connections (direct + proxy agents) and replace them
|
|
239
|
-
* with fresh instances. The global dispatcher's `dispatch` method captures
|
|
240
|
-
* `direct` and `proxies` by reference, so subsequent requests automatically
|
|
241
|
-
* use the new agents — no need to call `setGlobalDispatcher` again.
|
|
242
|
-
*
|
|
243
|
-
* Call this after a network error to discard stale/half-closed sockets that
|
|
244
|
-
* would otherwise cause every retry to wait ~60 s before timing out.
|
|
245
|
-
*
|
|
246
|
-
* Under the Bun runtime (which doesn't use undici) this is a no-op.
|
|
247
|
-
*/
|
|
248
|
-
function resetConnections() {
|
|
249
|
-
if (typeof Bun !== "undefined") return;
|
|
250
|
-
if (!direct) return;
|
|
251
|
-
const oldDirect = direct;
|
|
252
|
-
const oldProxies = proxies;
|
|
253
|
-
direct = new Agent(agentOptions);
|
|
254
|
-
proxies = /* @__PURE__ */ new Map();
|
|
255
|
-
oldDirect.close().catch(() => {});
|
|
256
|
-
for (const agent of oldProxies.values()) agent.close().catch(() => {});
|
|
257
|
-
consola.debug("Connection pool reset — stale sockets cleared");
|
|
258
|
-
}
|
|
259
|
-
//#endregion
|
|
260
120
|
//#region src/account.ts
|
|
261
121
|
const addAccount = defineCommand({
|
|
262
122
|
meta: {
|
|
@@ -1490,6 +1350,10 @@ accountRoutes.post("/", async (c) => {
|
|
|
1490
1350
|
const body = await c.req.json();
|
|
1491
1351
|
if (!body.githubToken || !body.label) return c.json({ error: "githubToken and label are required" }, 400);
|
|
1492
1352
|
const account = await accountManager.addAccount(body.githubToken, body.label, body.accountType);
|
|
1353
|
+
if (body.proxy) {
|
|
1354
|
+
account.proxy = body.proxy;
|
|
1355
|
+
await accountManager.saveAccounts();
|
|
1356
|
+
}
|
|
1493
1357
|
return c.json({ account: sanitiseAccount(account) }, 201);
|
|
1494
1358
|
} catch (error) {
|
|
1495
1359
|
consola.warn(`Error adding account: ${rootCause(error)}`);
|
|
@@ -1767,40 +1631,37 @@ async function checkRateLimit(state) {
|
|
|
1767
1631
|
*/
|
|
1768
1632
|
const FETCH_TIMEOUT_MS = 12e4;
|
|
1769
1633
|
/**
|
|
1770
|
-
* Retry delays in ms.
|
|
1771
|
-
* (see `resetConnections`), so retries use fresh sockets.
|
|
1772
|
-
*
|
|
1773
|
-
* We only allow 1 retry (2 total attempts) to minimize credit waste.
|
|
1774
|
-
* Timeout errors are NOT retried at all — they indicate the request likely
|
|
1775
|
-
* reached Copilot (consuming a credit) and the upstream is slow or the
|
|
1776
|
-
* proxy killed the connection mid-flight.
|
|
1777
|
-
*/
|
|
1778
|
-
const RETRY_DELAYS = [2e3];
|
|
1779
|
-
/**
|
|
1780
|
-
* Timeout for retry attempts (waiting for response headers only).
|
|
1781
|
-
* Response headers typically arrive within 3–5 s, even on slow models.
|
|
1782
|
-
* 30 s is generous enough for a fresh socket to connect and receive
|
|
1783
|
-
* headers, while still failing fast when the upstream is truly down.
|
|
1634
|
+
* Retry delays in ms. Empty = no retries.
|
|
1784
1635
|
*
|
|
1785
|
-
*
|
|
1786
|
-
*
|
|
1787
|
-
*
|
|
1636
|
+
* IMPORTANT: Retries are DISABLED because each attempt to Copilot consumes
|
|
1637
|
+
* a credit, and the caller (e.g. Claude Code) already retries at the
|
|
1638
|
+
* application level. Our retry + Claude Code's retry created a request
|
|
1639
|
+
* cascade that caused account bans (367 requests in 52 minutes).
|
|
1788
1640
|
*/
|
|
1789
|
-
const
|
|
1641
|
+
const RETRY_DELAYS = [];
|
|
1642
|
+
/** Minimum interval (ms) between requests on the same account. */
|
|
1643
|
+
const MIN_SAME_ACCOUNT_INTERVAL_MS = 1e3;
|
|
1644
|
+
/** Random jitter range (ms) added when switching between accounts. */
|
|
1645
|
+
const ACCOUNT_SWITCH_JITTER_MIN_MS = 1e3;
|
|
1646
|
+
const ACCOUNT_SWITCH_JITTER_MAX_MS = 5e3;
|
|
1647
|
+
/** Track the last-used account ID to detect account switches. */
|
|
1648
|
+
let lastUsedAccountId;
|
|
1790
1649
|
/**
|
|
1791
1650
|
* Wrapper around `fetch()` that aborts if the server doesn't respond within
|
|
1792
1651
|
* `timeoutMs`. The timeout only covers the period until the response headers
|
|
1793
1652
|
* arrive – once the body starts streaming, the timeout is cleared so that
|
|
1794
1653
|
* long SSE responses are not interrupted.
|
|
1795
1654
|
*/
|
|
1796
|
-
async function fetchWithTimeout(url, init, timeoutMs = FETCH_TIMEOUT_MS) {
|
|
1655
|
+
async function fetchWithTimeout(url, init, { timeoutMs = FETCH_TIMEOUT_MS, accountId, accountProxy } = {}) {
|
|
1797
1656
|
const controller = new AbortController();
|
|
1798
1657
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
1799
1658
|
try {
|
|
1800
|
-
|
|
1659
|
+
const fetchOptions = {
|
|
1801
1660
|
...init,
|
|
1802
1661
|
signal: controller.signal
|
|
1803
|
-
}
|
|
1662
|
+
};
|
|
1663
|
+
if (accountId) fetchOptions.dispatcher = getAccountDispatcher(accountId, accountProxy);
|
|
1664
|
+
return await fetch(url, fetchOptions);
|
|
1804
1665
|
} catch (error) {
|
|
1805
1666
|
if (error instanceof DOMException && error.name === "AbortError") throw new Error(`Request timed out after ${timeoutMs}ms`);
|
|
1806
1667
|
throw error;
|
|
@@ -1814,12 +1675,16 @@ async function fetchWithTimeout(url, init, timeoutMs = FETCH_TIMEOUT_MS) {
|
|
|
1814
1675
|
* Returns `{ response }` on success.
|
|
1815
1676
|
* Throws the last network error if all retries are exhausted.
|
|
1816
1677
|
*/
|
|
1817
|
-
async function fetchWithRetry(url, buildInit) {
|
|
1678
|
+
async function fetchWithRetry(url, buildInit, { accountId, accountProxy } = {}) {
|
|
1818
1679
|
let lastError;
|
|
1819
1680
|
const maxAttempts = RETRY_DELAYS.length + 1;
|
|
1820
1681
|
for (let attempt = 0; attempt < maxAttempts; attempt++) try {
|
|
1821
|
-
const timeout =
|
|
1822
|
-
return await fetchWithTimeout(url, buildInit(),
|
|
1682
|
+
const timeout = FETCH_TIMEOUT_MS;
|
|
1683
|
+
return await fetchWithTimeout(url, buildInit(), {
|
|
1684
|
+
timeoutMs: timeout,
|
|
1685
|
+
accountId,
|
|
1686
|
+
accountProxy
|
|
1687
|
+
});
|
|
1823
1688
|
} catch (error) {
|
|
1824
1689
|
lastError = error;
|
|
1825
1690
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -1827,7 +1692,8 @@ async function fetchWithRetry(url, buildInit) {
|
|
|
1827
1692
|
consola.warn(`Request timed out on attempt ${attempt + 1}/${maxAttempts} — not retrying (credit likely consumed):`, msg);
|
|
1828
1693
|
break;
|
|
1829
1694
|
}
|
|
1830
|
-
if (attempt === 0)
|
|
1695
|
+
if (attempt === 0) if (accountId) resetAccountConnections(accountId);
|
|
1696
|
+
else resetConnections();
|
|
1831
1697
|
if (attempt < maxAttempts - 1) {
|
|
1832
1698
|
const delay = RETRY_DELAYS[attempt];
|
|
1833
1699
|
consola.warn(`Network error on attempt ${attempt + 1}/${maxAttempts}, retrying in ${delay}ms:`, error instanceof Error ? error.message : error);
|
|
@@ -1841,8 +1707,8 @@ async function fetchWithRetry(url, buildInit) {
|
|
|
1841
1707
|
* finishes (return or throw), not when the outer function returns.
|
|
1842
1708
|
* Also tracks active streams for the proxy-tunnel keepalive mechanism.
|
|
1843
1709
|
*/
|
|
1844
|
-
async function* wrapGeneratorWithRelease(gen, releaseSlot) {
|
|
1845
|
-
notifyStreamStart();
|
|
1710
|
+
async function* wrapGeneratorWithRelease(gen, releaseSlot, accountInfo) {
|
|
1711
|
+
notifyStreamStart(accountInfo);
|
|
1846
1712
|
let streamError = false;
|
|
1847
1713
|
try {
|
|
1848
1714
|
yield* gen;
|
|
@@ -1850,9 +1716,10 @@ async function* wrapGeneratorWithRelease(gen, releaseSlot) {
|
|
|
1850
1716
|
streamError = true;
|
|
1851
1717
|
throw error;
|
|
1852
1718
|
} finally {
|
|
1853
|
-
notifyStreamEnd();
|
|
1719
|
+
notifyStreamEnd(accountInfo);
|
|
1854
1720
|
releaseSlot();
|
|
1855
|
-
if (streamError)
|
|
1721
|
+
if (streamError) if (accountInfo?.accountId) resetAccountConnections(accountInfo.accountId);
|
|
1722
|
+
else resetConnections();
|
|
1856
1723
|
}
|
|
1857
1724
|
}
|
|
1858
1725
|
/**
|
|
@@ -1940,7 +1807,10 @@ const createChatCompletions = async (payload) => {
|
|
|
1940
1807
|
const releaseSlot = await modelRouter.acquireSlot(resolvedModel);
|
|
1941
1808
|
try {
|
|
1942
1809
|
const result = await dispatchRequest(thinkingPayload);
|
|
1943
|
-
if (Symbol.asyncIterator in result)
|
|
1810
|
+
if (Symbol.asyncIterator in result) {
|
|
1811
|
+
const accountInfo = result.__accountInfo;
|
|
1812
|
+
return wrapGeneratorWithRelease(result, releaseSlot, accountInfo);
|
|
1813
|
+
}
|
|
1944
1814
|
releaseSlot();
|
|
1945
1815
|
return result;
|
|
1946
1816
|
} catch (error) {
|
|
@@ -1974,7 +1844,10 @@ const createChatCompletions = async (payload) => {
|
|
|
1974
1844
|
async function retryWithoutReasoning(payload, releaseSlot) {
|
|
1975
1845
|
try {
|
|
1976
1846
|
const result = await dispatchRequest(payload);
|
|
1977
|
-
if (Symbol.asyncIterator in result)
|
|
1847
|
+
if (Symbol.asyncIterator in result) {
|
|
1848
|
+
const accountInfo = result.__accountInfo;
|
|
1849
|
+
return wrapGeneratorWithRelease(result, releaseSlot, accountInfo);
|
|
1850
|
+
}
|
|
1978
1851
|
releaseSlot();
|
|
1979
1852
|
return result;
|
|
1980
1853
|
} catch (retryError) {
|
|
@@ -1989,7 +1862,10 @@ async function retryWithoutReasoning(payload, releaseSlot) {
|
|
|
1989
1862
|
async function retryWithDowngradedReasoning(payload, releaseSlot) {
|
|
1990
1863
|
try {
|
|
1991
1864
|
const result = await dispatchRequest(payload);
|
|
1992
|
-
if (Symbol.asyncIterator in result)
|
|
1865
|
+
if (Symbol.asyncIterator in result) {
|
|
1866
|
+
const accountInfo = result.__accountInfo;
|
|
1867
|
+
return wrapGeneratorWithRelease(result, releaseSlot, accountInfo);
|
|
1868
|
+
}
|
|
1993
1869
|
releaseSlot();
|
|
1994
1870
|
return result;
|
|
1995
1871
|
} catch (retryError) {
|
|
@@ -2117,11 +1993,29 @@ async function createWithMultiAccount(payload) {
|
|
|
2117
1993
|
copilotApiEndpoint: account.copilotApiEndpoint,
|
|
2118
1994
|
accountType: account.accountType,
|
|
2119
1995
|
githubToken: account.githubToken,
|
|
2120
|
-
vsCodeVersion: state.vsCodeVersion
|
|
1996
|
+
vsCodeVersion: state.vsCodeVersion,
|
|
1997
|
+
machineId: account.machineId,
|
|
1998
|
+
sessionId: account.sessionId,
|
|
1999
|
+
proxy: account.proxy
|
|
2121
2000
|
};
|
|
2122
2001
|
try {
|
|
2123
|
-
|
|
2002
|
+
if (account.lastRequestAt) {
|
|
2003
|
+
const elapsed = Date.now() - account.lastRequestAt;
|
|
2004
|
+
if (elapsed < MIN_SAME_ACCOUNT_INTERVAL_MS) await new Promise((r) => setTimeout(r, MIN_SAME_ACCOUNT_INTERVAL_MS - elapsed));
|
|
2005
|
+
}
|
|
2006
|
+
if (lastUsedAccountId && lastUsedAccountId !== account.id) {
|
|
2007
|
+
const jitter = ACCOUNT_SWITCH_JITTER_MIN_MS + Math.random() * (ACCOUNT_SWITCH_JITTER_MAX_MS - ACCOUNT_SWITCH_JITTER_MIN_MS);
|
|
2008
|
+
consola.debug(`Account switch jitter: ${Math.round(jitter)}ms (${lastUsedAccountId.slice(0, 8)} → ${account.id.slice(0, 8)})`);
|
|
2009
|
+
await new Promise((r) => setTimeout(r, jitter));
|
|
2010
|
+
}
|
|
2011
|
+
lastUsedAccountId = account.id;
|
|
2012
|
+
const result = await doFetch(payload, tokenSource, account.id);
|
|
2013
|
+
account.lastRequestAt = Date.now();
|
|
2124
2014
|
accountManager.markAccountSuccess(account.id);
|
|
2015
|
+
if (Symbol.asyncIterator in result) result.__accountInfo = {
|
|
2016
|
+
accountId: account.id,
|
|
2017
|
+
accountProxy: account.proxy
|
|
2018
|
+
};
|
|
2125
2019
|
return result;
|
|
2126
2020
|
} catch (error) {
|
|
2127
2021
|
lastError = error;
|
|
@@ -2145,7 +2039,7 @@ async function createWithMultiAccount(payload) {
|
|
|
2145
2039
|
* call it with different `TokenSource` objects while keeping all the header
|
|
2146
2040
|
* construction / retry / error‐surfacing logic in one place.
|
|
2147
2041
|
*/
|
|
2148
|
-
async function doFetch(payload, source) {
|
|
2042
|
+
async function doFetch(payload, source, accountId) {
|
|
2149
2043
|
const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x) => x.type === "image_url"));
|
|
2150
2044
|
const isAgentCall = payload.messages.some((msg) => ["assistant", "tool"].includes(msg.role));
|
|
2151
2045
|
const buildHeaders = () => ({
|
|
@@ -2166,7 +2060,10 @@ async function doFetch(payload, source) {
|
|
|
2166
2060
|
method: "POST",
|
|
2167
2061
|
headers: buildHeaders(),
|
|
2168
2062
|
body: bodyString
|
|
2169
|
-
})
|
|
2063
|
+
}), {
|
|
2064
|
+
accountId,
|
|
2065
|
+
accountProxy: source.proxy
|
|
2066
|
+
});
|
|
2170
2067
|
if (!response.ok) {
|
|
2171
2068
|
const errorBody = await response.text();
|
|
2172
2069
|
if (response.status === 400) consola.warn(`400: ${errorBody}`);
|
|
@@ -3188,7 +3085,7 @@ async function validateGitHubToken(token) {
|
|
|
3188
3085
|
state.githubToken = token;
|
|
3189
3086
|
consola.info("Using provided GitHub token");
|
|
3190
3087
|
try {
|
|
3191
|
-
const { getGitHubUser } = await import("./get-user-
|
|
3088
|
+
const { getGitHubUser } = await import("./get-user-BSYESgez.js");
|
|
3192
3089
|
const user = await getGitHubUser();
|
|
3193
3090
|
consola.info(`Logged in as ${user.login}`);
|
|
3194
3091
|
} catch (error) {
|
|
@@ -3239,10 +3136,10 @@ async function runServer(options) {
|
|
|
3239
3136
|
try {
|
|
3240
3137
|
await setupCopilotToken();
|
|
3241
3138
|
} catch (error) {
|
|
3242
|
-
const { HTTPError } = await import("./error-
|
|
3139
|
+
const { HTTPError } = await import("./error-BDOdv5Up.js");
|
|
3243
3140
|
if (error instanceof HTTPError && error.response.status === 401) {
|
|
3244
3141
|
consola.error("Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked");
|
|
3245
|
-
const { clearGithubToken } = await import("./token-
|
|
3142
|
+
const { clearGithubToken } = await import("./token-C9gxxgzi.js");
|
|
3246
3143
|
await clearGithubToken();
|
|
3247
3144
|
consola.info("Please restart to re-authenticate");
|
|
3248
3145
|
}
|