@jeffreycao/copilot-api 1.10.9 → 1.10.11

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.
Files changed (33) hide show
  1. package/README.md +53 -213
  2. package/README.zh-CN.md +47 -209
  3. package/dist/auth-BO_SkMVw.js +116 -0
  4. package/dist/auth-BO_SkMVw.js.map +1 -0
  5. package/dist/{check-usage-BdXGp1Wr.js → check-usage-D-W6VD7k.js} +3 -4
  6. package/dist/{check-usage-BdXGp1Wr.js.map → check-usage-D-W6VD7k.js.map} +1 -1
  7. package/dist/{proxy-DvlF9a-7.js → config-ztdkLu9o.js} +83 -70
  8. package/dist/config-ztdkLu9o.js.map +1 -0
  9. package/dist/{debug-C_TBkyUw.js → debug-BVHmoCzY.js} +17 -7
  10. package/dist/debug-BVHmoCzY.js.map +1 -0
  11. package/dist/main.js +5 -5
  12. package/dist/{mcp-CTb-DbQH.js → mcp-DZgcvqQY.js} +2 -2
  13. package/dist/{mcp-CTb-DbQH.js.map → mcp-DZgcvqQY.js.map} +1 -1
  14. package/dist/{server-FPXzFkg9.js → server-2tRe3sDu.js} +1798 -1713
  15. package/dist/server-2tRe3sDu.js.map +1 -0
  16. package/dist/{start-CbKg_0bY.js → start-CM-b3DRX.js} +4 -6
  17. package/dist/{start-CbKg_0bY.js.map → start-CM-b3DRX.js.map} +1 -1
  18. package/dist/token-BVXHiYEl.js +1875 -0
  19. package/dist/token-BVXHiYEl.js.map +1 -0
  20. package/dist/{tool-search-D3SN0jX-.js → tool-search-wA-fLduL.js} +1 -1
  21. package/dist/{tool-search-D3SN0jX-.js.map → tool-search-wA-fLduL.js.map} +1 -1
  22. package/package.json +2 -2
  23. package/dist/auth-BHa2OHXf.js +0 -45
  24. package/dist/auth-BHa2OHXf.js.map +0 -1
  25. package/dist/debug-C_TBkyUw.js.map +0 -1
  26. package/dist/paths-DC-mqCY3.js +0 -30
  27. package/dist/paths-DC-mqCY3.js.map +0 -1
  28. package/dist/proxy-DvlF9a-7.js.map +0 -1
  29. package/dist/server-FPXzFkg9.js.map +0 -1
  30. package/dist/token-Dj8XsAxn.js +0 -170
  31. package/dist/token-Dj8XsAxn.js.map +0 -1
  32. package/dist/utils-jHLgqAq2.js +0 -657
  33. package/dist/utils-jHLgqAq2.js.map +0 -1
@@ -1,657 +0,0 @@
1
- import consola from "consola";
2
- import { readFile } from "node:fs/promises";
3
- import { networkInterfaces } from "node:os";
4
- import path from "node:path";
5
- import { createHash, randomUUID } from "node:crypto";
6
- import { exec } from "node:child_process";
7
- import { AsyncLocalStorage } from "node:async_hooks";
8
- //#region src/lib/state.ts
9
- const state = {
10
- accountType: "individual",
11
- manualApprove: false,
12
- rateLimitWait: false,
13
- showToken: false,
14
- verbose: false,
15
- vsCodeDeviceId: randomUUID()
16
- };
17
- const compactSystemPromptStarts = ["You are a helpful AI assistant tasked with summarizing conversations", "You are an anchored context summarization assistant for coding sessions."];
18
- const compactTextOnlyGuard = "CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.";
19
- const compactSummaryPromptStart = "Your task is to create a detailed summary of the conversation so far";
20
- const compactAutoContinuePromptStarts = [
21
- "This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.",
22
- "Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.",
23
- "The previous request exceeded the provider's size limit due to large media attachments. The conversation was compacted and media files were removed from context."
24
- ];
25
- const compactMessageSections = ["Pending Tasks:", "Current Work:"];
26
- //#endregion
27
- //#region src/lib/opencode.ts
28
- const execAsync = (command) => {
29
- return new Promise((resolve, reject) => {
30
- exec(command, (error, stdout) => {
31
- if (error) {
32
- reject(error);
33
- return;
34
- }
35
- resolve(stdout);
36
- });
37
- });
38
- };
39
- let opencodeVersionCache;
40
- const getGlobalNpmRoot = async () => {
41
- return (await execAsync("npm root -g")).trim();
42
- };
43
- async function resolveOpencodeVersion() {
44
- try {
45
- const npmRootPath = await getGlobalNpmRoot();
46
- const packageJson = await readFile(path.join(npmRootPath, "opencode-ai", "package.json"), "utf8");
47
- const { version } = JSON.parse(packageJson);
48
- opencodeVersionCache = version;
49
- } catch (error) {
50
- consola.warn(`Failed to resolve opencode version`, error);
51
- }
52
- }
53
- const initOpencodeVersion = () => {
54
- if (process.env.COPILOT_API_OAUTH_APP?.trim() !== "opencode") return Promise.resolve();
55
- return resolveOpencodeVersion();
56
- };
57
- const getCachedOpencodeVersion = () => {
58
- return opencodeVersionCache;
59
- };
60
- //#endregion
61
- //#region src/lib/request-context.ts
62
- const TRACE_ID_MAX_LENGTH = 64;
63
- const TRACE_ID_PATTERN = /^\w[\w.-]*$/;
64
- const asyncLocalStorage = new AsyncLocalStorage();
65
- const requestContext = {
66
- getStore: () => asyncLocalStorage.getStore(),
67
- run: (context, callback) => asyncLocalStorage.run(context, callback)
68
- };
69
- function generateTraceId() {
70
- return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
71
- }
72
- function resolveTraceId(traceId) {
73
- const candidate = traceId?.trim();
74
- if (!candidate || candidate.length > TRACE_ID_MAX_LENGTH || !TRACE_ID_PATTERN.test(candidate)) return generateTraceId();
75
- return candidate;
76
- }
77
- //#endregion
78
- //#region src/lib/api-config.ts
79
- const isOpencodeOauthApp = () => {
80
- return process.env.COPILOT_API_OAUTH_APP?.trim() === "opencode";
81
- };
82
- const normalizeDomain = (input) => {
83
- return input.trim().replace(/^https?:\/\//u, "").replace(/\/+$/u, "");
84
- };
85
- const getEnterpriseDomain = () => {
86
- const raw = (process.env.COPILOT_API_ENTERPRISE_URL ?? "").trim();
87
- if (!raw) return null;
88
- return normalizeDomain(raw) || null;
89
- };
90
- const getGitHubBaseUrl = () => {
91
- const resolvedDomain = getEnterpriseDomain();
92
- return resolvedDomain ? `https://${resolvedDomain}` : GITHUB_BASE_URL;
93
- };
94
- const getGitHubApiBaseUrl = () => {
95
- const resolvedDomain = getEnterpriseDomain();
96
- return resolvedDomain ? `https://api.${resolvedDomain}` : GITHUB_API_BASE_URL;
97
- };
98
- const getOpencodeOauthHeaders = () => {
99
- return {
100
- Accept: "application/json",
101
- "Content-Type": "application/json",
102
- "User-Agent": getOpencodeVersion()
103
- };
104
- };
105
- const getOpencodeLLMHeaders = () => {
106
- return {
107
- Accept: "application/json",
108
- "Content-Type": "application/json",
109
- "User-Agent": OPENCODE_LLM_USER_AGENT
110
- };
111
- };
112
- const normalizeOpencodeUserAgent = (userAgent) => {
113
- const candidate = userAgent.trim();
114
- const opencodeProduct = candidate.match(/^opencode\/[^\s,]+/u)?.[0];
115
- if (!opencodeProduct || candidate.includes(`, ${opencodeProduct}`)) return candidate;
116
- return `${candidate}, ${opencodeProduct}`;
117
- };
118
- const getOauthUrls = () => {
119
- const githubBaseUrl = getGitHubBaseUrl();
120
- return {
121
- deviceCodeUrl: `${githubBaseUrl}/login/device/code`,
122
- accessTokenUrl: `${githubBaseUrl}/login/oauth/access_token`
123
- };
124
- };
125
- const getOauthAppConfig = () => {
126
- if (isOpencodeOauthApp()) return {
127
- clientId: OPENCODE_GITHUB_CLIENT_ID,
128
- headers: getOpencodeOauthHeaders(),
129
- scope: GITHUB_APP_SCOPES
130
- };
131
- return {
132
- clientId: GITHUB_CLIENT_ID,
133
- headers: standardHeaders(),
134
- scope: GITHUB_APP_SCOPES
135
- };
136
- };
137
- const prepareForCompact = (headers, compactType) => {
138
- if (compactType) {
139
- headers["x-initiator"] = "agent";
140
- if (!isOpencodeOauthApp() && compactType === 1) {
141
- headers["x-interaction-type"] = "conversation-compaction";
142
- headers["openai-intent"] = "conversation-agent";
143
- }
144
- }
145
- };
146
- const prepareInteractionHeaders = (sessionId, isSubagent, headers) => {
147
- const sendInteractionHeaders = !isOpencodeOauthApp();
148
- if (isSubagent) {
149
- headers["x-initiator"] = "agent";
150
- if (sendInteractionHeaders) headers["x-interaction-type"] = "conversation-subagent";
151
- }
152
- if (sessionId && sendInteractionHeaders) headers["x-interaction-id"] = sessionId;
153
- };
154
- const standardHeaders = () => ({
155
- "content-type": "application/json",
156
- accept: "application/json"
157
- });
158
- const getOpencodeVersion = () => {
159
- const version = getCachedOpencodeVersion();
160
- if (version) return "opencode/" + version;
161
- return OPENCODE_VERSION;
162
- };
163
- const OPENCODE_VERSION = "opencode/1.14.29";
164
- const OPENCODE_LLM_USER_AGENT = "opencode/1.14.29 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.13, opencode/1.14.29";
165
- const COPILOT_VERSION = "0.47.1";
166
- const EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`;
167
- const USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`;
168
- const CLAUDE_AGENT_USER_AGENT = "vscode_claude_code/2.1.112 (external, sdk-ts, agent-sdk/0.2.112)";
169
- const EDITOR_WEBSOCKET_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`;
170
- const API_VERSION = "2026-01-09";
171
- const WEBSOCKET_API_VERSION = API_VERSION;
172
- const copilotBaseUrl = (state) => {
173
- const enterpriseDomain = getEnterpriseDomain();
174
- if (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;
175
- if (isOpencodeOauthApp()) return "https://api.githubcopilot.com";
176
- if (state.copilotApiUrl) return state.copilotApiUrl;
177
- return state.accountType === "individual" ? "https://api.githubcopilot.com" : `https://api.${state.accountType}.githubcopilot.com`;
178
- };
179
- const prepareMessageProxyHeaders = (headers) => {
180
- if (isOpencodeOauthApp()) return;
181
- const requestIdValue = randomUUID();
182
- headers["x-agent-task-id"] = requestIdValue;
183
- headers["x-request-id"] = requestIdValue;
184
- headers["x-interaction-type"] = "messages-proxy";
185
- headers["openai-intent"] = "messages-proxy";
186
- headers["user-agent"] = CLAUDE_AGENT_USER_AGENT;
187
- delete headers["copilot-integration-id"];
188
- };
189
- const githubUserHeaders = (state) => {
190
- if (isOpencodeOauthApp()) return {
191
- Authorization: `Bearer ${state.githubToken}`,
192
- "User-Agent": getOpencodeVersion()
193
- };
194
- return {
195
- accept: "application/vnd.github+json",
196
- authorization: `token ${state.githubToken}`,
197
- "user-agent": USER_AGENT,
198
- "x-github-api-version": "2022-11-28",
199
- "x-vscode-user-agent-library-version": "electron-fetch"
200
- };
201
- };
202
- const copilotModelsHeaders = (state) => {
203
- if (isOpencodeOauthApp()) return {
204
- Authorization: `Bearer ${state.copilotToken}`,
205
- "User-Agent": getOpencodeVersion()
206
- };
207
- const headers = githubCopilotHeaders(state);
208
- headers["x-interaction-type"] = "model-access";
209
- headers["openai-intent"] = "model-access";
210
- delete headers["x-interaction-id"];
211
- delete headers["content-type"];
212
- return headers;
213
- };
214
- const copilotHeaders = (state, requestId, vision = false) => {
215
- if (isOpencodeOauthApp()) {
216
- const headers = {
217
- Authorization: `Bearer ${state.copilotToken}`,
218
- ...getOpencodeLLMHeaders(),
219
- "Openai-Intent": "conversation-edits"
220
- };
221
- const store = requestContext.getStore();
222
- const userAgent = store?.userAgent.trim();
223
- if (userAgent?.startsWith("opencode/")) headers["User-Agent"] = normalizeOpencodeUserAgent(userAgent);
224
- if (store?.sessionAffinity) headers["x-session-affinity"] = store.sessionAffinity;
225
- if (store?.parentSessionId) headers["x-parent-session-id"] = store.parentSessionId;
226
- if (vision) headers["Copilot-Vision-Request"] = "true";
227
- return headers;
228
- }
229
- return githubCopilotHeaders(state, requestId, vision);
230
- };
231
- const copilotWebSocketHeaders = (preparedHeaders) => {
232
- if (isOpencodeOauthApp()) return omitHeader(preparedHeaders, "x-initiator");
233
- const requestId = getPreparedHeader(preparedHeaders, "x-request-id") ?? randomUUID();
234
- const source = createHeaderResolver(preparedHeaders);
235
- const headers = {
236
- Authorization: source("authorization"),
237
- "X-Request-Id": requestId,
238
- "OpenAI-Intent": source("openai-intent", "conversation-agent"),
239
- "X-GitHub-Api-Version": source("x-github-api-version", WEBSOCKET_API_VERSION),
240
- "X-Interaction-Id": source("x-interaction-id", requestId),
241
- "X-Interaction-Type": source("x-interaction-type", "conversation-agent"),
242
- "X-Agent-Task-Id": source("x-agent-task-id", requestId)
243
- };
244
- setPreparedHeader(headers, "VScode-SessionId", preparedHeaders, "vscode-sessionid");
245
- setPreparedHeader(headers, "VScode-MachineId", preparedHeaders, "vscode-machineid");
246
- Object.assign(headers, {
247
- "Editor-Device-Id": source("editor-device-id"),
248
- "Editor-Plugin-Version": source("editor-plugin-version", EDITOR_WEBSOCKET_PLUGIN_VERSION),
249
- "Editor-Version": source("editor-version"),
250
- "Copilot-Integration-Id": source("copilot-integration-id", "vscode-chat")
251
- });
252
- setPreparedHeader(headers, "Copilot-Vision-Request", preparedHeaders, "copilot-vision-request");
253
- headers["user-agent"] = "node";
254
- return headers;
255
- };
256
- const createHeaderResolver = (headers) => (headerName, fallback = "") => getPreparedHeader(headers, headerName) ?? fallback;
257
- const getPreparedHeader = (headers, headerName) => {
258
- const normalizedHeaderName = headerName.toLowerCase();
259
- return Object.entries(headers).find(([key]) => key.toLowerCase() === normalizedHeaderName)?.[1];
260
- };
261
- const setPreparedHeader = (target, targetHeaderName, source, sourceHeaderName) => {
262
- const value = getPreparedHeader(source, sourceHeaderName);
263
- if (value) target[targetHeaderName] = value;
264
- };
265
- const omitHeader = (headers, headerName) => {
266
- const normalizedHeaderName = headerName.toLowerCase();
267
- return Object.fromEntries(Object.entries(headers).filter(([key]) => key.toLowerCase() !== normalizedHeaderName));
268
- };
269
- const githubCopilotHeaders = (state, requestId, vision = false) => {
270
- const requestIdValue = requestId ?? randomUUID();
271
- const headers = {
272
- Authorization: `Bearer ${state.copilotToken}`,
273
- "content-type": standardHeaders()["content-type"],
274
- "copilot-integration-id": "vscode-chat",
275
- "editor-device-id": state.vsCodeDeviceId,
276
- "editor-version": `vscode/${state.vsCodeVersion}`,
277
- "editor-plugin-version": EDITOR_PLUGIN_VERSION,
278
- "user-agent": USER_AGENT,
279
- "openai-intent": "conversation-agent",
280
- "x-github-api-version": API_VERSION,
281
- "x-request-id": requestIdValue,
282
- "x-vscode-user-agent-library-version": "electron-fetch",
283
- "x-agent-task-id": requestIdValue,
284
- "x-interaction-type": "conversation-agent"
285
- };
286
- if (vision) headers["copilot-vision-request"] = "true";
287
- if (state.macMachineId) headers["vscode-machineid"] = state.macMachineId;
288
- if (state.vsCodeSessionId) headers["vscode-sessionid"] = state.vsCodeSessionId;
289
- return headers;
290
- };
291
- const GITHUB_API_BASE_URL = "https://api.github.com";
292
- const githubHeaders = (state) => {
293
- if (isOpencodeOauthApp()) return {
294
- Authorization: `Bearer ${state.githubToken}`,
295
- ...getOpencodeOauthHeaders()
296
- };
297
- return {
298
- authorization: `token ${state.githubToken}`,
299
- "user-agent": USER_AGENT,
300
- "x-github-api-version": "2025-04-01",
301
- "x-vscode-user-agent-library-version": "electron-fetch"
302
- };
303
- };
304
- const GITHUB_BASE_URL = "https://github.com";
305
- const GITHUB_CLIENT_ID = "Iv1.b507a08c87ecfe98";
306
- const GITHUB_APP_SCOPES = ["read:user"].join(" ");
307
- const OPENCODE_GITHUB_CLIENT_ID = "Ov23li8tweQw6odWQebz";
308
- //#endregion
309
- //#region src/lib/error.ts
310
- var HTTPError = class extends Error {
311
- response;
312
- constructor(message, response) {
313
- super(message);
314
- this.response = response;
315
- }
316
- };
317
- async function forwardError(c, error) {
318
- consola.error("Error occurred:", error);
319
- if (error instanceof HTTPError) {
320
- if (error.response.status === 429) for (const [name, value] of error.response.headers) {
321
- const lowerName = name.toLowerCase();
322
- if (lowerName === "retry-after" || lowerName.startsWith("x-")) c.header(name, value);
323
- }
324
- const errorText = await error.response.text();
325
- let errorJson;
326
- try {
327
- errorJson = JSON.parse(errorText);
328
- } catch {
329
- errorJson = errorText;
330
- }
331
- consola.error("HTTP error:", errorJson);
332
- return c.json({ error: {
333
- message: errorText,
334
- type: "error"
335
- } }, error.response.status);
336
- }
337
- return c.json({ error: {
338
- message: error.message,
339
- type: "error"
340
- } }, 500);
341
- }
342
- //#endregion
343
- //#region src/services/github/get-copilot-usage.ts
344
- const getCopilotUsage = async (githubToken) => {
345
- const resolvedGithubToken = githubToken ?? state.githubToken;
346
- if (!resolvedGithubToken) throw new Error("GitHub token not found");
347
- const authState = {
348
- ...state,
349
- githubToken: resolvedGithubToken
350
- };
351
- const response = await fetch(`${getGitHubApiBaseUrl()}/copilot_internal/user`, { headers: githubHeaders(authState) });
352
- if (!response.ok) throw new HTTPError("Failed to get Copilot usage", response);
353
- return await response.json();
354
- };
355
- //#endregion
356
- //#region src/services/copilot/get-models.ts
357
- const getModels = async () => {
358
- consola.info(`Fetching models from ${copilotBaseUrl(state)}/models`);
359
- const response = await fetch(`${copilotBaseUrl(state)}/models`, { headers: copilotModelsHeaders(state) });
360
- if (!response.ok) {
361
- const errorText = await response.clone().text();
362
- consola.error("Failed to get models response body", errorText);
363
- throw new HTTPError("Failed to get models", response);
364
- }
365
- return await response.json();
366
- };
367
- //#endregion
368
- //#region src/services/get-vscode-version.ts
369
- const FALLBACK = "1.119.1";
370
- async function getVSCodeVersion() {
371
- await Promise.resolve();
372
- return FALLBACK;
373
- }
374
- //#endregion
375
- //#region src/lib/deviceid.ts
376
- const WINDOWS_DEVICE_ID_KEY = String.raw`\SOFTWARE\Microsoft\DeveloperTools`;
377
- const WINDOWS_DEVICE_ID_NAME = "deviceid";
378
- const windows64Architectures = new Set([
379
- "AMD64",
380
- "ARM64",
381
- "IA64"
382
- ]);
383
- const getPosixHomeDir = () => {
384
- if (!process.env.HOME) throw new Error("Home directory not found");
385
- return process.env.HOME;
386
- };
387
- const getDeviceIdFilePath = () => {
388
- let folder;
389
- switch (process.platform) {
390
- case "darwin":
391
- folder = path.posix.join(getPosixHomeDir(), "Library", "Application Support");
392
- break;
393
- case "linux":
394
- folder = process.env.XDG_CACHE_HOME ?? path.posix.join(getPosixHomeDir(), ".cache");
395
- break;
396
- default: throw new Error("Unsupported platform");
397
- }
398
- return path.posix.join(folder, "Microsoft", "DeveloperTools", "deviceid");
399
- };
400
- const isMissingFileError = (error) => {
401
- return error instanceof Error && "code" in error && error.code === "ENOENT";
402
- };
403
- const readStoredDeviceIdFile = async (filePath) => {
404
- const { readFile } = await import("node:fs/promises");
405
- try {
406
- return await readFile(filePath, "utf8");
407
- } catch (error) {
408
- if (isMissingFileError(error)) return;
409
- throw error;
410
- }
411
- };
412
- const writeStoredDeviceIdFile = async (filePath, deviceId) => {
413
- const { mkdir, writeFile } = await import("node:fs/promises");
414
- await mkdir(path.posix.dirname(filePath), { recursive: true });
415
- await writeFile(filePath, deviceId, "utf8");
416
- };
417
- const getWindowsRegistryArch = () => {
418
- const architecture = (process.env.PROCESSOR_ARCHITEW6432 ?? process.env.PROCESSOR_ARCHITECTURE)?.toUpperCase();
419
- return architecture && windows64Architectures.has(architecture) ? "x64" : void 0;
420
- };
421
- const loadWinreg = async () => {
422
- const module = await import("winreg");
423
- return "default" in module ? module.default : module;
424
- };
425
- const isMissingRegistryError = (error) => {
426
- if (!error) return false;
427
- const errorCode = Number(error.code);
428
- return Number.isFinite(errorCode) && errorCode === 1;
429
- };
430
- const createWindowsRegistry = async () => {
431
- const Winreg = await loadWinreg();
432
- return {
433
- registry: new Winreg({
434
- hive: Winreg.HKCU,
435
- key: WINDOWS_DEVICE_ID_KEY,
436
- arch: getWindowsRegistryArch()
437
- }),
438
- regSz: Winreg.REG_SZ
439
- };
440
- };
441
- const readRegistryString = async (registry, name) => {
442
- return new Promise((resolve, reject) => {
443
- registry.get(name, (error, item) => {
444
- if (isMissingRegistryError(error)) {
445
- resolve(void 0);
446
- return;
447
- }
448
- if (error) {
449
- reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
450
- return;
451
- }
452
- resolve(item?.value);
453
- });
454
- });
455
- };
456
- const writeRegistryString = async ({ registry, regSz, name, value }) => {
457
- return new Promise((resolve, reject) => {
458
- registry.set(name, regSz, value, (error) => {
459
- if (error) {
460
- reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
461
- return;
462
- }
463
- resolve();
464
- });
465
- });
466
- };
467
- const getStoredVSCodeDeviceId = async () => {
468
- switch (process.platform) {
469
- case "win32": {
470
- const { registry } = await createWindowsRegistry();
471
- return readRegistryString(registry, WINDOWS_DEVICE_ID_NAME);
472
- }
473
- case "darwin":
474
- case "linux": return readStoredDeviceIdFile(getDeviceIdFilePath());
475
- default: throw new Error("Unsupported platform");
476
- }
477
- };
478
- const setStoredVSCodeDeviceId = async (deviceId) => {
479
- switch (process.platform) {
480
- case "win32": {
481
- const { registry, regSz } = await createWindowsRegistry();
482
- await writeRegistryString({
483
- registry,
484
- regSz,
485
- name: WINDOWS_DEVICE_ID_NAME,
486
- value: deviceId
487
- });
488
- return;
489
- }
490
- case "darwin":
491
- case "linux":
492
- await writeStoredDeviceIdFile(getDeviceIdFilePath(), deviceId);
493
- return;
494
- default: throw new Error("Unsupported platform");
495
- }
496
- };
497
- const createVSCodeDeviceId = () => randomUUID().toLowerCase();
498
- async function getVSCodeDeviceId() {
499
- let deviceId;
500
- try {
501
- deviceId = await getStoredVSCodeDeviceId();
502
- } catch (error) {
503
- consola.debug("Failed to read VSCode device id", error);
504
- }
505
- if (deviceId) return deviceId;
506
- const newDeviceId = createVSCodeDeviceId();
507
- try {
508
- await setStoredVSCodeDeviceId(newDeviceId);
509
- } catch (error) {
510
- consola.warn("Failed to persist VSCode device id, using ephemeral id", error);
511
- }
512
- return newDeviceId;
513
- }
514
- //#endregion
515
- //#region src/lib/utils.ts
516
- const sleep = (ms) => new Promise((resolve) => {
517
- setTimeout(resolve, ms);
518
- });
519
- const isNullish = (value) => value === null || value === void 0;
520
- async function cacheModels() {
521
- const models = await getModels();
522
- state.models = {
523
- ...models,
524
- data: models.data.filter((model) => model.model_picker_enabled || model.capabilities.type === "embeddings")
525
- };
526
- }
527
- const cacheVSCodeVersion = async () => {
528
- const response = await getVSCodeVersion();
529
- state.vsCodeVersion = response;
530
- consola.info(`Using VSCode version: ${response}`);
531
- };
532
- const invalidMacAddresses = new Set([
533
- "00:00:00:00:00:00",
534
- "ff:ff:ff:ff:ff:ff",
535
- "ac:de:48:00:11:22"
536
- ]);
537
- function validateMacAddress(candidate) {
538
- const tempCandidate = candidate.replaceAll("-", ":").toLowerCase();
539
- return !invalidMacAddresses.has(tempCandidate);
540
- }
541
- function getMac() {
542
- const ifaces = networkInterfaces();
543
- for (const name in ifaces) {
544
- const networkInterface = ifaces[name];
545
- if (networkInterface) {
546
- for (const { mac } of networkInterface) if (validateMacAddress(mac)) return mac;
547
- }
548
- }
549
- return null;
550
- }
551
- const cacheMacMachineId = () => {
552
- const macAddress = getMac() ?? randomUUID();
553
- state.macMachineId = createHash("sha256").update(macAddress, "utf8").digest("hex");
554
- consola.debug(`Using machine ID: ${state.macMachineId}`);
555
- };
556
- const cacheVsCodeDeviceId = async () => {
557
- state.vsCodeDeviceId = await getVSCodeDeviceId();
558
- consola.debug(`Using VSCode device ID: ${state.vsCodeDeviceId}`);
559
- };
560
- const SESSION_REFRESH_BASE_MS = 3600 * 1e3;
561
- const SESSION_REFRESH_JITTER_MS = 1200 * 1e3;
562
- let vsCodeSessionRefreshTimer = null;
563
- const generateSessionId = () => {
564
- state.vsCodeSessionId = randomUUID() + Date.now().toString();
565
- consola.debug(`Generated VSCode session ID: ${state.vsCodeSessionId}`);
566
- };
567
- const stopVsCodeSessionRefreshLoop = () => {
568
- if (vsCodeSessionRefreshTimer) {
569
- clearTimeout(vsCodeSessionRefreshTimer);
570
- vsCodeSessionRefreshTimer = null;
571
- }
572
- };
573
- const scheduleSessionIdRefresh = () => {
574
- const delay = SESSION_REFRESH_BASE_MS + Math.floor(Math.random() * SESSION_REFRESH_JITTER_MS);
575
- consola.debug(`Scheduling next VSCode session ID refresh in ${Math.round(delay / 1e3)} seconds`);
576
- stopVsCodeSessionRefreshLoop();
577
- vsCodeSessionRefreshTimer = setTimeout(() => {
578
- try {
579
- generateSessionId();
580
- } catch (error) {
581
- consola.error("Failed to refresh session ID, rescheduling...", error);
582
- } finally {
583
- scheduleSessionIdRefresh();
584
- }
585
- }, delay);
586
- };
587
- const cacheVsCodeSessionId = () => {
588
- stopVsCodeSessionRefreshLoop();
589
- generateSessionId();
590
- scheduleSessionIdRefresh();
591
- };
592
- const isRecord = (value) => typeof value === "object" && value !== null;
593
- const getUserIdJsonField = (userIdPayload, field) => {
594
- const value = userIdPayload?.[field];
595
- return typeof value === "string" && value.length > 0 ? value : null;
596
- };
597
- const parseJsonUserId = (userId) => {
598
- try {
599
- const parsed = JSON.parse(userId);
600
- return isRecord(parsed) ? parsed : null;
601
- } catch {
602
- return null;
603
- }
604
- };
605
- const parseUserIdMetadata = (userId) => {
606
- if (!userId || typeof userId !== "string") return {
607
- safetyIdentifier: null,
608
- sessionId: null
609
- };
610
- const legacySafetyIdentifier = userId.match(/user_([^_]+)_account/)?.[1] ?? null;
611
- const legacySessionId = userId.match(/_session_(.+)$/)?.[1] ?? null;
612
- const parsedUserId = legacySafetyIdentifier && legacySessionId ? null : parseJsonUserId(userId);
613
- return {
614
- safetyIdentifier: legacySafetyIdentifier ?? getUserIdJsonField(parsedUserId, "device_id") ?? getUserIdJsonField(parsedUserId, "account_uuid"),
615
- sessionId: legacySessionId ?? getUserIdJsonField(parsedUserId, "session_id")
616
- };
617
- };
618
- const findLastUserContent = (messages) => {
619
- for (let i = messages.length - 1; i >= 0; i--) {
620
- const msg = messages[i];
621
- if (msg.role === "user" && msg.content) {
622
- if (typeof msg.content === "string") return msg.content;
623
- else if (Array.isArray(msg.content)) {
624
- const array = msg.content.filter((n) => n.type !== "tool_result").map((n) => ({
625
- ...n,
626
- cache_control: void 0
627
- }));
628
- if (array.length > 0) return JSON.stringify(array);
629
- }
630
- }
631
- }
632
- return null;
633
- };
634
- const generateRequestIdFromPayload = (payload, sessionId) => {
635
- const messages = payload.messages;
636
- if (messages) {
637
- const lastUserContent = typeof messages === "string" ? messages : findLastUserContent(messages);
638
- if (lastUserContent) return getUUID((sessionId ?? "") + (state.macMachineId ?? "") + lastUserContent);
639
- }
640
- return randomUUID();
641
- };
642
- const getRootSessionId = (anthropicPayload, c) => {
643
- const userId = anthropicPayload.metadata?.user_id;
644
- const sessionId = userId ? parseUserIdMetadata(userId).sessionId || void 0 : c.req.header("x-session-id");
645
- return sessionId ? getUUID(sessionId) : sessionId;
646
- };
647
- const getUUID = (content) => {
648
- const uuidBytes = createHash("sha256").update(content).digest().subarray(0, 16);
649
- uuidBytes[6] = uuidBytes[6] & 15 | 64;
650
- uuidBytes[8] = uuidBytes[8] & 63 | 128;
651
- const uuidHex = uuidBytes.toString("hex");
652
- return `${uuidHex.slice(0, 8)}-${uuidHex.slice(8, 12)}-${uuidHex.slice(12, 16)}-${uuidHex.slice(16, 20)}-${uuidHex.slice(20)}`;
653
- };
654
- //#endregion
655
- export { initOpencodeVersion as A, isOpencodeOauthApp as C, generateTraceId as D, prepareMessageProxyHeaders as E, compactTextOnlyGuard as F, state as I, compactMessageSections as M, compactSummaryPromptStart as N, requestContext as O, compactSystemPromptStarts as P, githubUserHeaders as S, prepareInteractionHeaders as T, copilotWebSocketHeaders as _, cacheVsCodeSessionId as a, getOauthUrls as b, getUUID as c, sleep as d, getCopilotUsage as f, copilotHeaders as g, copilotBaseUrl as h, cacheVsCodeDeviceId as i, compactAutoContinuePromptStarts as j, resolveTraceId as k, isNullish as l, forwardError as m, cacheModels as n, generateRequestIdFromPayload as o, HTTPError as p, cacheVSCodeVersion as r, getRootSessionId as s, cacheMacMachineId as t, parseUserIdMetadata as u, getGitHubApiBaseUrl as v, prepareForCompact as w, githubHeaders as x, getOauthAppConfig as y };
656
-
657
- //# sourceMappingURL=utils-jHLgqAq2.js.map