@jeffreycao/copilot-api 1.16.0 → 1.16.2

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.
@@ -1,8 +1,7 @@
1
- import { A as PATHS, b as isResponsesApiWebSocketEnabled, d as getRawProviderConfig, k as setProviderConfig } from "./config-B3hsNlmB.js";
1
+ import { A as PATHS, O as isResponsesApiWebSocketEnabled, c as setProviderConfig, n as getRawProviderConfig } from "./config-BAC1UYyJ.js";
2
2
  import consola from "consola";
3
3
  import { createHash, randomBytes, randomUUID } from "node:crypto";
4
4
  import fs, { readFile } from "node:fs/promises";
5
- import { networkInterfaces } from "node:os";
6
5
  import path from "node:path";
7
6
  import { createServer } from "node:http";
8
7
  import { events } from "fetch-event-stream";
@@ -289,6 +288,42 @@ const getProxyUrl = (url) => {
289
288
  return getProxyForUrl(url.replace(/^wss:/, "https:").replace(/^ws:/, "http:"));
290
289
  };
291
290
  //#endregion
291
+ //#region src/services/responses-websocket-helpers.ts
292
+ const encodePoolKeyPart = (value) => encodeURIComponent(value);
293
+ const getErrorMessage = (error) => {
294
+ if (error instanceof Error && error.message) return error.message;
295
+ return String(error);
296
+ };
297
+ const createResponsesErrorServerSentEventChunk = (message) => {
298
+ const errorEvent = {
299
+ code: null,
300
+ message,
301
+ param: null,
302
+ sequence_number: 0,
303
+ type: "error"
304
+ };
305
+ return {
306
+ event: errorEvent.type,
307
+ data: JSON.stringify(errorEvent)
308
+ };
309
+ };
310
+ const isTerminalResponsesStreamChunk = (chunk) => {
311
+ if (!chunk.data || chunk.data === "[DONE]") return false;
312
+ try {
313
+ const parsed = JSON.parse(chunk.data);
314
+ return parsed.type === "response.completed" || parsed.type === "response.failed" || parsed.type === "response.incomplete" || parsed.type === "error";
315
+ } catch {
316
+ return false;
317
+ }
318
+ };
319
+ const createResponsesSafeStream = async function* (source) {
320
+ try {
321
+ yield* source;
322
+ } catch (error) {
323
+ yield createResponsesErrorServerSentEventChunk(getErrorMessage(error));
324
+ }
325
+ };
326
+ //#endregion
292
327
  //#region src/lib/request-context.ts
293
328
  const TRACE_ID_MAX_LENGTH = 64;
294
329
  const TRACE_ID_PATTERN = /^\w[\w.-]*$/;
@@ -488,20 +523,13 @@ const buildCodexResponsesWebSocketPoolKey = (payload, headers, baseUrl) => {
488
523
  const forwardCodexResponsesOverWebSocket = (payload, requestHeaders, baseUrl) => {
489
524
  return createCodexResponsesWebSocketStream(prepareCodexResponsesWebSocketRequest(payload, requestHeaders, baseUrl));
490
525
  };
491
- const createCodexResponsesWebSocketStream = (request) => createCodexResponsesSafeStream(createPooledWebSocketStream(request, {
526
+ const createCodexResponsesWebSocketStream = (request) => createResponsesSafeStream(createPooledWebSocketStream(request, {
492
527
  createChunk: createCodexResponsesWebSocketStreamChunk,
493
- isTerminalChunk: isTerminalCodexResponsesWebSocketChunk,
528
+ isTerminalChunk: isTerminalResponsesStreamChunk,
494
529
  openErrorMessage: "Failed to create codex responses websocket",
495
530
  streamErrorMessage: "Codex responses websocket stream error",
496
531
  terminalChunkMissingMessage: "Codex responses websocket ended without a terminal response"
497
532
  }));
498
- const createCodexResponsesSafeStream = async function* (source) {
499
- try {
500
- yield* source;
501
- } catch (error) {
502
- yield createResponsesErrorServerSentEventChunk(getErrorMessage(error));
503
- }
504
- };
505
533
  const createCodexResponsesWebSocketStreamChunk = (data) => {
506
534
  if (data === "[DONE]") return { data };
507
535
  try {
@@ -519,33 +547,6 @@ const createCodexResponsesWebSocketStreamChunk = (data) => {
519
547
  return { data };
520
548
  }
521
549
  };
522
- const isTerminalCodexResponsesWebSocketChunk = (chunk) => {
523
- if (!chunk.data || chunk.data === "[DONE]") return false;
524
- try {
525
- const parsed = JSON.parse(chunk.data);
526
- return parsed.type === "response.completed" || parsed.type === "response.failed" || parsed.type === "response.incomplete" || parsed.type === "error";
527
- } catch {
528
- return false;
529
- }
530
- };
531
- const createResponsesErrorServerSentEventChunk = (message) => {
532
- const errorEvent = {
533
- code: null,
534
- message,
535
- param: null,
536
- sequence_number: 0,
537
- type: "error"
538
- };
539
- return {
540
- event: errorEvent.type,
541
- data: JSON.stringify(errorEvent)
542
- };
543
- };
544
- const getErrorMessage = (error) => {
545
- if (error instanceof Error && error.message) return error.message;
546
- return String(error);
547
- };
548
- const encodePoolKeyPart = (value) => encodeURIComponent(value);
549
550
  //#endregion
550
551
  //#region src/lib/oauth/codex.ts
551
552
  const CALLBACK_HOST = "127.0.0.1";
@@ -1208,273 +1209,13 @@ async function getDeviceCode() {
1208
1209
  return await response.json();
1209
1210
  }
1210
1211
  //#endregion
1211
- //#region src/services/copilot/get-models.ts
1212
- const getModels = async () => {
1213
- consola.info(`Fetching models from ${copilotBaseUrl(state)}/models`);
1214
- const response = await fetch(`${copilotBaseUrl(state)}/models`, { headers: copilotModelsHeaders(state) });
1215
- if (!response.ok) {
1216
- const errorText = await response.clone().text();
1217
- consola.error("Failed to get models response body", errorText);
1218
- throw new HTTPError("Failed to get models", response);
1219
- }
1220
- return await response.json();
1221
- };
1222
- //#endregion
1223
- //#region src/services/get-vscode-version.ts
1224
- const FALLBACK = "1.130.0";
1225
- async function getVSCodeVersion() {
1226
- await Promise.resolve();
1227
- return FALLBACK;
1228
- }
1229
- //#endregion
1230
- //#region src/lib/deviceid.ts
1231
- const WINDOWS_DEVICE_ID_KEY = String.raw`\SOFTWARE\Microsoft\DeveloperTools`;
1232
- const WINDOWS_DEVICE_ID_NAME = "deviceid";
1233
- const windows64Architectures = new Set([
1234
- "AMD64",
1235
- "ARM64",
1236
- "IA64"
1237
- ]);
1238
- const getPosixHomeDir = () => {
1239
- if (!process.env.HOME) throw new Error("Home directory not found");
1240
- return process.env.HOME;
1241
- };
1242
- const getDeviceIdFilePath = () => {
1243
- let folder;
1244
- switch (process.platform) {
1245
- case "darwin":
1246
- folder = path.posix.join(getPosixHomeDir(), "Library", "Application Support");
1247
- break;
1248
- case "linux":
1249
- folder = process.env.XDG_CACHE_HOME ?? path.posix.join(getPosixHomeDir(), ".cache");
1250
- break;
1251
- default: throw new Error("Unsupported platform");
1252
- }
1253
- return path.posix.join(folder, "Microsoft", "DeveloperTools", "deviceid");
1254
- };
1255
- const isMissingFileError = (error) => {
1256
- return error instanceof Error && "code" in error && error.code === "ENOENT";
1257
- };
1258
- const readStoredDeviceIdFile = async (filePath) => {
1259
- const { readFile } = await import("node:fs/promises");
1260
- try {
1261
- return await readFile(filePath, "utf8");
1262
- } catch (error) {
1263
- if (isMissingFileError(error)) return;
1264
- throw error;
1265
- }
1266
- };
1267
- const writeStoredDeviceIdFile = async (filePath, deviceId) => {
1268
- const { mkdir, writeFile } = await import("node:fs/promises");
1269
- await mkdir(path.posix.dirname(filePath), { recursive: true });
1270
- await writeFile(filePath, deviceId, "utf8");
1271
- };
1272
- const getWindowsRegistryArch = () => {
1273
- const architecture = (process.env.PROCESSOR_ARCHITEW6432 ?? process.env.PROCESSOR_ARCHITECTURE)?.toUpperCase();
1274
- return architecture && windows64Architectures.has(architecture) ? "x64" : void 0;
1275
- };
1276
- const loadWinreg = async () => {
1277
- const module = await import("winreg");
1278
- return "default" in module ? module.default : module;
1279
- };
1280
- const isMissingRegistryError = (error) => {
1281
- if (!error) return false;
1282
- const errorCode = Number(error.code);
1283
- return Number.isFinite(errorCode) && errorCode === 1;
1284
- };
1285
- const createWindowsRegistry = async () => {
1286
- const Winreg = await loadWinreg();
1287
- return {
1288
- registry: new Winreg({
1289
- hive: Winreg.HKCU,
1290
- key: WINDOWS_DEVICE_ID_KEY,
1291
- arch: getWindowsRegistryArch()
1292
- }),
1293
- regSz: Winreg.REG_SZ
1294
- };
1295
- };
1296
- const readRegistryString = async (registry, name) => {
1297
- return new Promise((resolve, reject) => {
1298
- registry.get(name, (error, item) => {
1299
- if (isMissingRegistryError(error)) {
1300
- resolve(void 0);
1301
- return;
1302
- }
1303
- if (error) {
1304
- reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
1305
- return;
1306
- }
1307
- resolve(item?.value);
1308
- });
1309
- });
1310
- };
1311
- const writeRegistryString = async ({ registry, regSz, name, value }) => {
1312
- return new Promise((resolve, reject) => {
1313
- registry.set(name, regSz, value, (error) => {
1314
- if (error) {
1315
- reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
1316
- return;
1317
- }
1318
- resolve();
1319
- });
1320
- });
1321
- };
1322
- const getStoredVSCodeDeviceId = async () => {
1323
- switch (process.platform) {
1324
- case "win32": {
1325
- const { registry } = await createWindowsRegistry();
1326
- return readRegistryString(registry, WINDOWS_DEVICE_ID_NAME);
1327
- }
1328
- case "darwin":
1329
- case "linux": return readStoredDeviceIdFile(getDeviceIdFilePath());
1330
- default: throw new Error("Unsupported platform");
1331
- }
1332
- };
1333
- const setStoredVSCodeDeviceId = async (deviceId) => {
1334
- switch (process.platform) {
1335
- case "win32": {
1336
- const { registry, regSz } = await createWindowsRegistry();
1337
- await writeRegistryString({
1338
- registry,
1339
- regSz,
1340
- name: WINDOWS_DEVICE_ID_NAME,
1341
- value: deviceId
1342
- });
1343
- return;
1344
- }
1345
- case "darwin":
1346
- case "linux":
1347
- await writeStoredDeviceIdFile(getDeviceIdFilePath(), deviceId);
1348
- return;
1349
- default: throw new Error("Unsupported platform");
1350
- }
1351
- };
1352
- const createVSCodeDeviceId = () => randomUUID().toLowerCase();
1353
- async function getVSCodeDeviceId() {
1354
- let deviceId;
1355
- try {
1356
- deviceId = await getStoredVSCodeDeviceId();
1357
- } catch (error) {
1358
- consola.debug("Failed to read VSCode device id", error);
1359
- }
1360
- if (deviceId) return deviceId;
1361
- const newDeviceId = createVSCodeDeviceId();
1362
- try {
1363
- await setStoredVSCodeDeviceId(newDeviceId);
1364
- } catch (error) {
1365
- consola.warn("Failed to persist VSCode device id, using ephemeral id", error);
1366
- }
1367
- return newDeviceId;
1368
- }
1369
- //#endregion
1370
1212
  //#region src/lib/utils.ts
1371
1213
  const sleep = (ms) => new Promise((resolve) => {
1372
1214
  setTimeout(resolve, ms);
1373
1215
  });
1374
1216
  const isNullish = (value) => value === null || value === void 0;
1375
- const MODELS_REFRESH_BASE_MS = 1800 * 1e3;
1376
- let modelsRefreshTimer = null;
1377
- const stopModelsRefreshLoop = () => {
1378
- if (modelsRefreshTimer) {
1379
- clearTimeout(modelsRefreshTimer);
1380
- modelsRefreshTimer = null;
1381
- }
1382
- };
1383
- const refreshModels = async (fetcher) => {
1384
- const prevIds = new Set(state.models?.data.map((m) => m.id) ?? []);
1385
- const models = await fetcher();
1386
- state.models = {
1387
- ...models,
1388
- data: models.data.filter((model) => model.policy?.state !== "disabled" && (model.model_picker_enabled || model.capabilities.type === "embeddings"))
1389
- };
1390
- const nextIds = state.models.data.map((m) => m.id);
1391
- const added = nextIds.filter((id) => !prevIds.has(id));
1392
- if (added.length > 0) consola.info(`Models refresh: ${added.length} new`);
1393
- else consola.debug(`Models refresh: no changes (${nextIds.length} total)`);
1394
- };
1395
- const scheduleModelsRefresh = (fetcher, intervalMs) => {
1396
- const delay = intervalMs + Math.floor(Math.random() * (intervalMs / 6));
1397
- consola.debug(`Scheduling next models refresh in ${Math.round(delay / 1e3)} seconds`);
1398
- stopModelsRefreshLoop();
1399
- modelsRefreshTimer = setTimeout(async () => {
1400
- try {
1401
- await refreshModels(fetcher);
1402
- } catch (error) {
1403
- consola.warn("Failed to refresh models, keeping previous cache.", error);
1404
- } finally {
1405
- scheduleModelsRefresh(fetcher, intervalMs);
1406
- }
1407
- }, delay);
1408
- };
1409
- async function cacheModels(fetcher = getModels, intervalMs = MODELS_REFRESH_BASE_MS) {
1410
- await refreshModels(fetcher);
1411
- scheduleModelsRefresh(fetcher, intervalMs);
1412
- }
1413
- const cacheVSCodeVersion = async () => {
1414
- const response = await getVSCodeVersion();
1415
- state.vsCodeVersion = response;
1416
- consola.info(`Using VSCode version: ${response}`);
1417
- };
1418
- const invalidMacAddresses = new Set([
1419
- "00:00:00:00:00:00",
1420
- "ff:ff:ff:ff:ff:ff",
1421
- "ac:de:48:00:11:22"
1422
- ]);
1423
- function validateMacAddress(candidate) {
1424
- const tempCandidate = candidate.replaceAll("-", ":").toLowerCase();
1425
- return !invalidMacAddresses.has(tempCandidate);
1426
- }
1427
- function getMac() {
1428
- const ifaces = networkInterfaces();
1429
- for (const name in ifaces) {
1430
- const networkInterface = ifaces[name];
1431
- if (networkInterface) {
1432
- for (const { mac } of networkInterface) if (validateMacAddress(mac)) return mac;
1433
- }
1434
- }
1435
- return null;
1436
- }
1437
- const cacheMacMachineId = () => {
1438
- const macAddress = getMac() ?? randomUUID();
1439
- state.macMachineId = createHash("sha256").update(macAddress, "utf8").digest("hex");
1440
- consola.debug(`Using machine ID: ${state.macMachineId}`);
1441
- };
1442
- const cacheVsCodeDeviceId = async () => {
1443
- state.vsCodeDeviceId = await getVSCodeDeviceId();
1444
- consola.debug(`Using VSCode device ID: ${state.vsCodeDeviceId}`);
1445
- };
1446
- const SESSION_REFRESH_BASE_MS = 3600 * 1e3;
1447
- const SESSION_REFRESH_JITTER_MS = 1200 * 1e3;
1448
- let vsCodeSessionRefreshTimer = null;
1449
- const generateSessionId = () => {
1450
- state.vsCodeSessionId = randomUUID() + Date.now().toString();
1451
- consola.debug(`Generated VSCode session ID: ${state.vsCodeSessionId}`);
1452
- };
1453
- const stopVsCodeSessionRefreshLoop = () => {
1454
- if (vsCodeSessionRefreshTimer) {
1455
- clearTimeout(vsCodeSessionRefreshTimer);
1456
- vsCodeSessionRefreshTimer = null;
1457
- }
1458
- };
1459
- const scheduleSessionIdRefresh = () => {
1460
- const delay = SESSION_REFRESH_BASE_MS + Math.floor(Math.random() * SESSION_REFRESH_JITTER_MS);
1461
- consola.debug(`Scheduling next VSCode session ID refresh in ${Math.round(delay / 1e3)} seconds`);
1462
- stopVsCodeSessionRefreshLoop();
1463
- vsCodeSessionRefreshTimer = setTimeout(() => {
1464
- try {
1465
- generateSessionId();
1466
- } catch (error) {
1467
- consola.error("Failed to refresh session ID, rescheduling...", error);
1468
- } finally {
1469
- scheduleSessionIdRefresh();
1470
- }
1471
- }, delay);
1472
- };
1473
- const cacheVsCodeSessionId = () => {
1474
- stopVsCodeSessionRefreshLoop();
1475
- generateSessionId();
1476
- scheduleSessionIdRefresh();
1477
- };
1217
+ const isAsyncIterable = (value) => Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
1218
+ const isResponsesStream = (value) => isAsyncIterable(value);
1478
1219
  const isRecord = (value) => typeof value === "object" && value !== null;
1479
1220
  const getUserIdJsonField = (userIdPayload, field) => {
1480
1221
  const value = userIdPayload?.[field];
@@ -1759,6 +1500,6 @@ async function logUser() {
1759
1500
  state.tokenBasedBilling = copilotUser.token_based_billing;
1760
1501
  }
1761
1502
  //#endregion
1762
- export { loginCodex as A, HTTPError as B, prepareMessageProxyHeaders as C, compactSummaryPromptStart as D, compactMessageSections as E, requestContext as F, resolveTraceId as I, createPooledWebSocketStream as L, buildCodexRequestHeaders as M, forwardCodexResponses as N, compactSystemPromptStarts as O, generateTraceId as P, createWebSocketUrl as R, prepareInteractionHeaders as S, compactAutoContinuePromptStarts as T, forwardError as V, readGitHubToken as _, setupGitHubToken as a, copilotWebSocketHeaders as b, cacheVSCodeVersion as c, generateRequestIdFromPayload as d, getRootSessionId as f, getCopilotUsage as g, parseUserIdMetadata as h, setupCopilotToken as i, CODEX_API_BASE_URL as j, compactTextOnlyGuard as k, cacheVsCodeDeviceId as l, isNullish as m, persistCodexCredentials as n, cacheMacMachineId as o, getUUID as p, setupCodexToken as r, cacheModels as s, logUser as t, cacheVsCodeSessionId as u, copilotBaseUrl as v, initOpencodeVersion as w, prepareForCompact as x, copilotHeaders as y, state as z };
1503
+ export { buildCodexRequestHeaders as A, state as B, compactAutoContinuePromptStarts as C, compactTextOnlyGuard as D, compactSystemPromptStarts as E, createResponsesSafeStream as F, forwardError as H, encodePoolKeyPart as I, isTerminalResponsesStreamChunk as L, generateTraceId as M, requestContext as N, loginCodex as O, resolveTraceId as P, createPooledWebSocketStream as R, initOpencodeVersion as S, compactSummaryPromptStart as T, HTTPError as V, copilotModelsHeaders as _, setupGitHubToken as a, prepareInteractionHeaders as b, getUUID as c, isResponsesStream as d, parseUserIdMetadata as f, copilotHeaders as g, copilotBaseUrl as h, setupCopilotToken as i, forwardCodexResponses as j, CODEX_API_BASE_URL as k, isAsyncIterable as l, readGitHubToken as m, persistCodexCredentials as n, generateRequestIdFromPayload as o, getCopilotUsage as p, setupCodexToken as r, getRootSessionId as s, logUser as t, isNullish as u, copilotWebSocketHeaders as v, compactMessageSections as w, prepareMessageProxyHeaders as x, prepareForCompact as y, createWebSocketUrl as z };
1763
1504
 
1764
- //# sourceMappingURL=token-DArgO8vi.js.map
1505
+ //# sourceMappingURL=token-ByZO3ykJ.js.map