copilot-api-plus 1.2.0 → 1.2.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.
package/README.en.md CHANGED
@@ -49,6 +49,7 @@ English | [简体中文](README.md)
49
49
  | 🛡️ **Network Resilience** | 120s connection timeout + exponential backoff retry (2s/5s/10s) |
50
50
  | ✂️ **Context Passthrough** | Full context passthrough to upstream API; clients (e.g. Claude Code) manage compression |
51
51
  | 🔍 **Smart Model Matching** | Handles model name format differences (date suffixes, dash/dot versions, etc.) |
52
+ | 🧠 **Thinking Chain** | Automatically enables deep thinking (thinking/reasoning) for supported models, improving code quality |
52
53
 
53
54
  ---
54
55
 
@@ -573,8 +574,8 @@ For Anthropic endpoints (`/v1/messages`), `translateModelName` also handles lega
573
574
  Each API request outputs a log line with model name, status code, and duration:
574
575
 
575
576
  ```log
576
- [claude-opus-4-6] 13:13:39 <-- POST /v1/messages?beta=true
577
- [claude-opus-4-6] 13:13:59 --> POST /v1/messages?beta=true 200 20.1s
577
+ [claude-opus-4-6 thinking] 13:13:39 <-- POST /v1/messages?beta=true
578
+ [claude-opus-4-6 thinking] 13:13:59 --> POST /v1/messages?beta=true 200 20.1s
578
579
  ```
579
580
 
580
581
  ### Network Resilience
package/README.md CHANGED
@@ -50,6 +50,7 @@
50
50
  | 🛡️ **网络弹性** | 120s 连接超时 + 指数退避重试(2s/5s/10s) |
51
51
  | ✂️ **上下文透传** | 全量透传上下文至上游 API,由客户端(如 Claude Code)自行管理压缩 |
52
52
  | 🔍 **智能模型匹配** | 自动处理模型名格式差异(日期后缀、dash/dot 版本号等) |
53
+ | 🧠 **Thinking 思考链** | 自动为支持的模型启用深度思考(thinking/reasoning),提升代码质量 |
53
54
 
54
55
  ---
55
56
 
@@ -736,8 +737,8 @@ Anthropic 格式的模型名(如 `claude-opus-4-6`)和 Copilot 的模型列
736
737
  每次 API 请求会输出一行日志,包含模型名、状态码和耗时:
737
738
 
738
739
  ```log
739
- [claude-opus-4-6] 13:13:39 <-- POST /v1/messages?beta=true
740
- [claude-opus-4-6] 13:13:59 --> POST /v1/messages?beta=true 200 20.1s
740
+ [claude-opus-4-6 thinking] 13:13:39 <-- POST /v1/messages?beta=true
741
+ [claude-opus-4-6 thinking] 13:13:59 --> POST /v1/messages?beta=true 200 20.1s
741
742
  ```
742
743
 
743
744
  ### 网络弹性
@@ -5,10 +5,10 @@ const standardHeaders = () => ({
5
5
  "content-type": "application/json",
6
6
  accept: "application/json"
7
7
  });
8
- const COPILOT_VERSION = "0.26.7";
8
+ const COPILOT_VERSION = "0.38.2";
9
9
  const EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`;
10
10
  const USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`;
11
- const API_VERSION = "2025-05-01";
11
+ const API_VERSION = "2025-10-01";
12
12
  const copilotBaseUrl = (source) => {
13
13
  if (source.copilotApiEndpoint) return source.copilotApiEndpoint;
14
14
  return source.accountType === "individual" ? "https://api.githubcopilot.com" : `https://api.${source.accountType}.githubcopilot.com`;
@@ -21,7 +21,9 @@ const copilotHeaders = (source, vision = false) => {
21
21
  "editor-version": `vscode/${source.vsCodeVersion}`,
22
22
  "editor-plugin-version": EDITOR_PLUGIN_VERSION,
23
23
  "user-agent": USER_AGENT,
24
- "openai-intent": "conversation-panel",
24
+ "openai-intent": "conversation-agent",
25
+ "x-interaction-type": "conversation-agent",
26
+ "x-agent-task-id": randomUUID(),
25
27
  "x-github-api-version": API_VERSION,
26
28
  "x-request-id": randomUUID(),
27
29
  "x-vscode-user-agent-library-version": "electron-fetch"
@@ -72,4 +74,4 @@ async function getGitHubUser(githubToken) {
72
74
  //#endregion
73
75
  export { GITHUB_BASE_URL as a, copilotHeaders as c, GITHUB_APP_SCOPES as i, githubHeaders as l, state as n, GITHUB_CLIENT_ID as o, GITHUB_API_BASE_URL as r, copilotBaseUrl as s, getGitHubUser as t, standardHeaders as u };
74
76
 
75
- //# sourceMappingURL=get-user-WQHD68Sz.js.map
77
+ //# sourceMappingURL=get-user-BT7hEyDN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-user-BT7hEyDN.js","names":[],"sources":["../src/lib/api-config.ts","../src/lib/state.ts","../src/services/github/get-user.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\"\n\nexport const standardHeaders = () => ({\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n})\n\nconst COPILOT_VERSION = \"0.38.2\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\n\n// Updated to match latest Zed implementation - 2025-10-01 returns Claude models\nconst API_VERSION = \"2025-10-01\"\n\n/**\n * Common interface for anything that can supply Copilot/GitHub credentials.\n *\n * Both `State` and `Account` satisfy this interface, so all header/URL\n * helpers can accept either without an explicit overload.\n */\nexport interface TokenSource {\n copilotToken?: string\n copilotApiEndpoint?: string\n accountType: string\n githubToken?: string\n vsCodeVersion?: string\n}\n\n// Re-export constants used by other modules for building headers manually\nexport { API_VERSION, EDITOR_PLUGIN_VERSION, USER_AGENT }\n\n// Use the API endpoint from token response if available, otherwise fall back to default\nexport const copilotBaseUrl = (source: TokenSource) => {\n if (source.copilotApiEndpoint) {\n return source.copilotApiEndpoint\n }\n return source.accountType === \"individual\" ?\n \"https://api.githubcopilot.com\"\n : `https://api.${source.accountType}.githubcopilot.com`\n}\nexport const copilotHeaders = (\n source: TokenSource,\n vision: boolean = false,\n) => {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${source.copilotToken}`,\n \"content-type\": standardHeaders()[\"content-type\"],\n \"copilot-integration-id\": \"vscode-chat\",\n \"editor-version\": `vscode/${source.vsCodeVersion}`,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"openai-intent\": \"conversation-agent\",\n \"x-interaction-type\": \"conversation-agent\",\n \"x-agent-task-id\": randomUUID(),\n \"x-github-api-version\": API_VERSION,\n \"x-request-id\": randomUUID(),\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\nexport const githubHeaders = (source: TokenSource) => ({\n ...standardHeaders(),\n authorization: `token ${source.githubToken}`,\n \"editor-version\": `vscode/${source.vsCodeVersion}`,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": API_VERSION,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n})\n\nexport const GITHUB_BASE_URL = \"https://github.com\"\nexport const GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\nexport const GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\n","import type { ModelsResponse } from \"~/services/copilot/get-models\"\n\nexport interface State {\n githubToken?: string\n copilotToken?: string\n copilotApiEndpoint?: string // API endpoint returned by token response\n\n accountType: string\n models?: ModelsResponse\n vsCodeVersion?: string\n\n manualApprove: boolean\n rateLimitWait: boolean\n showToken: boolean\n\n // Rate limiting configuration\n rateLimitSeconds?: number\n lastRequestTimestamp?: number\n\n // API key authentication\n apiKeys?: Array<string>\n\n // Multi-account mode\n multiAccountEnabled: boolean\n\n // Selected models (from --claude-code setup)\n selectedModel?: string\n selectedSmallModel?: string\n}\n\nexport const state: State = {\n accountType: \"individual\",\n manualApprove: false,\n rateLimitWait: false,\n showToken: false,\n multiAccountEnabled: false,\n}\n","import { GITHUB_API_BASE_URL, standardHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\n/**\n * Fetch the GitHub user profile.\n *\n * @param githubToken Optional explicit token. When omitted, falls back to\n * the global `state.githubToken`. Prefer passing a token\n * explicitly to avoid race conditions in multi-account mode.\n */\nexport async function getGitHubUser(githubToken?: string) {\n const token = githubToken ?? state.githubToken\n const response = await fetch(`${GITHUB_API_BASE_URL}/user`, {\n headers: {\n authorization: `token ${token}`,\n ...standardHeaders(),\n },\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get GitHub user\", response)\n\n return (await response.json()) as GithubUserResponse\n}\n\n// Trimmed for the sake of simplicity\ninterface GithubUserResponse {\n login: string\n}\n"],"mappings":";;;AAEA,MAAa,yBAAyB;CACpC,gBAAgB;CAChB,QAAQ;CACT;AAED,MAAM,kBAAkB;AACxB,MAAM,wBAAwB,gBAAgB;AAC9C,MAAM,aAAa,qBAAqB;AAGxC,MAAM,cAAc;AAoBpB,MAAa,kBAAkB,WAAwB;AACrD,KAAI,OAAO,mBACT,QAAO,OAAO;AAEhB,QAAO,OAAO,gBAAgB,eAC1B,kCACA,eAAe,OAAO,YAAY;;AAExC,MAAa,kBACX,QACA,SAAkB,UACf;CACH,MAAM,UAAkC;EACtC,eAAe,UAAU,OAAO;EAChC,gBAAgB,iBAAiB,CAAC;EAClC,0BAA0B;EAC1B,kBAAkB,UAAU,OAAO;EACnC,yBAAyB;EACzB,cAAc;EACd,iBAAiB;EACjB,sBAAsB;EACtB,mBAAmB,YAAY;EAC/B,wBAAwB;EACxB,gBAAgB,YAAY;EAC5B,uCAAuC;EACxC;AAED,KAAI,OAAQ,SAAQ,4BAA4B;AAEhD,QAAO;;AAGT,MAAa,sBAAsB;AACnC,MAAa,iBAAiB,YAAyB;CACrD,GAAG,iBAAiB;CACpB,eAAe,SAAS,OAAO;CAC/B,kBAAkB,UAAU,OAAO;CACnC,yBAAyB;CACzB,cAAc;CACd,wBAAwB;CACxB,uCAAuC;CACxC;AAED,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;AAChC,MAAa,oBAAoB,CAAC,YAAY,CAAC,KAAK,IAAI;;;AC/CxD,MAAa,QAAe;CAC1B,aAAa;CACb,eAAe;CACf,eAAe;CACf,WAAW;CACX,qBAAqB;CACtB;;;;;;;;;;ACzBD,eAAsB,cAAc,aAAsB;CACxD,MAAM,QAAQ,eAAe,MAAM;CACnC,MAAM,WAAW,MAAM,MAAM,GAAG,oBAAoB,QAAQ,EAC1D,SAAS;EACP,eAAe,SAAS;EACxB,GAAG,iBAAiB;EACrB,EACF,CAAC;AAEF,KAAI,CAAC,SAAS,GAAI,OAAM,IAAI,UAAU,6BAA6B,SAAS;AAE5E,QAAQ,MAAM,SAAS,MAAM"}
@@ -0,0 +1,3 @@
1
+ import "./error-CvwUkoEo.js";
2
+ import { t as getGitHubUser } from "./get-user-BT7hEyDN.js";
3
+ export { getGitHubUser };
package/dist/main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as forwardError, t as HTTPError } from "./error-CvwUkoEo.js";
3
- import { a as stopCopilotTokenRefresh, c as cacheModels, d as isNullish, f as sleep, g as ensurePaths, h as PATHS, i as setupGitHubToken, l as cacheVSCodeVersion, m as getCopilotUsage, n as refreshCopilotToken, o as pollAccessToken, p as accountManager, r as setupCopilotToken, s as getDeviceCode, t as clearGithubToken, u as findModel } from "./token-BMHteyQY.js";
4
- import { a as GITHUB_BASE_URL, c as copilotHeaders, n as state, o as GITHUB_CLIENT_ID, s as copilotBaseUrl, u as standardHeaders } from "./get-user-WQHD68Sz.js";
3
+ import { a as stopCopilotTokenRefresh, c as cacheModels, d as isNullish, f as sleep, g as ensurePaths, h as PATHS, i as setupGitHubToken, l as cacheVSCodeVersion, m as getCopilotUsage, n as refreshCopilotToken, o as pollAccessToken, p as accountManager, r as setupCopilotToken, s as getDeviceCode, t as clearGithubToken, u as findModel } from "./token-CsSZOO_Z.js";
4
+ import { a as GITHUB_BASE_URL, c as copilotHeaders, n as state, o as GITHUB_CLIENT_ID, s as copilotBaseUrl, u as standardHeaders } from "./get-user-BT7hEyDN.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { defineCommand, runMain } from "citty";
7
7
  import consola from "consola";
@@ -1320,29 +1320,47 @@ function formatDuration(ms) {
1320
1320
  return `${(ms / 1e3).toFixed(1)}s`;
1321
1321
  }
1322
1322
  /**
1323
- * Extract model name from request body
1323
+ * Extract model name and thinking status from request body.
1324
+ *
1325
+ * Thinking is considered active when:
1326
+ * - The client explicitly passes reasoning_effort / thinking_budget / thinking
1327
+ * - OR the backend will auto-inject thinking (default for all supported models)
1328
+ *
1329
+ * Since the proxy injects thinking for every model except those known to reject
1330
+ * it, we always mark thinking=true here. The `create-chat-completions` layer
1331
+ * will log the precise injection path separately.
1324
1332
  */
1325
- async function extractModel(c) {
1333
+ async function extractModelInfo(c) {
1326
1334
  try {
1327
- return (await c.req.raw.clone().json()).model;
1335
+ const body = await c.req.raw.clone().json();
1336
+ const clientThinking = Boolean(body.reasoning_effort) || Boolean(body.thinking_budget) || body.thinking?.type === "enabled";
1337
+ return {
1338
+ model: body.model,
1339
+ thinking: clientThinking || true
1340
+ };
1328
1341
  } catch {
1329
- return;
1342
+ return {};
1330
1343
  }
1331
1344
  }
1332
1345
  /**
1333
- * Custom logger middleware that shows model name before timestamp
1346
+ * Custom logger middleware that shows model name + thinking before timestamp
1334
1347
  *
1335
1348
  * Output format:
1336
- * [model] HH:mm:ss <-- METHOD /path
1337
- * [model] HH:mm:ss --> METHOD /path STATUS DURATION
1349
+ * [model thinking] HH:mm:ss <-- METHOD /path
1350
+ * [model thinking] HH:mm:ss --> METHOD /path STATUS DURATION
1338
1351
  */
1339
1352
  function modelLogger() {
1340
1353
  return async (c, next) => {
1341
1354
  const method = c.req.method;
1342
1355
  const fullPath = `${c.req.path}${c.req.raw.url.includes("?") ? `?${c.req.raw.url.split("?")[1]}` : ""}`;
1343
1356
  let model;
1344
- if (method === "POST" && c.req.header("content-type")?.includes("json")) model = await extractModel(c);
1345
- const modelPrefix = model ? `[${model}] ` : "";
1357
+ let thinking = false;
1358
+ if (method === "POST" && c.req.header("content-type")?.includes("json")) {
1359
+ const info = await extractModelInfo(c);
1360
+ model = info.model;
1361
+ thinking = info.thinking ?? false;
1362
+ }
1363
+ const modelPrefix = model ? `[${model}${thinking ? " thinking" : ""}] ` : "";
1346
1364
  const startTime = getTime();
1347
1365
  console.log(`${modelPrefix}${startTime} <-- ${method} ${fullPath}`);
1348
1366
  const start = Date.now();
@@ -1712,6 +1730,57 @@ async function* wrapGeneratorWithRelease(gen, releaseSlot) {
1712
1730
  releaseSlot();
1713
1731
  }
1714
1732
  }
1733
+ /**
1734
+ * Models that are known NOT to support the `reasoning_effort` parameter.
1735
+ * Populated at runtime: the first time a model returns 400 with
1736
+ * "Unrecognized request argument", it is added here and all future
1737
+ * requests to that model skip the injection automatically.
1738
+ */
1739
+ const reasoningUnsupportedModels = /* @__PURE__ */ new Set();
1740
+ /**
1741
+ * Compute an appropriate thinking_budget from model capabilities.
1742
+ * Returns undefined if the model does not support thinking.
1743
+ */
1744
+ function getThinkingBudget(model) {
1745
+ if (!model) return void 0;
1746
+ const { supports, limits } = model.capabilities;
1747
+ const maxBudget = supports.max_thinking_budget;
1748
+ if (!maxBudget || maxBudget <= 0) return void 0;
1749
+ const maxOutput = limits.max_output_tokens ?? 0;
1750
+ const upperBound = Math.min(maxBudget, Math.max(maxOutput - 1, 0));
1751
+ const lowerBound = supports.min_thinking_budget ?? 1024;
1752
+ return Math.max(upperBound, lowerBound);
1753
+ }
1754
+ /**
1755
+ * Inject thinking parameters into the payload based on model capabilities.
1756
+ *
1757
+ * Strategy (in priority order):
1758
+ * 1. If the client already set reasoning_effort or thinking_budget → keep as-is
1759
+ * 2. If model capabilities declare max_thinking_budget → inject thinking_budget
1760
+ * 3. Otherwise → inject reasoning_effort="high" (works on claude-*-4.6)
1761
+ *
1762
+ * The fallback to reasoning_effort ensures thinking works even when the
1763
+ * /models endpoint doesn't expose thinking budget fields.
1764
+ */
1765
+ function injectThinking(payload, resolvedModel) {
1766
+ if (payload.reasoning_effort || payload.thinking_budget) return payload;
1767
+ const budget = getThinkingBudget(findModel(resolvedModel));
1768
+ if (budget) return {
1769
+ ...payload,
1770
+ thinking_budget: budget
1771
+ };
1772
+ if (!reasoningUnsupportedModels.has(resolvedModel)) return {
1773
+ ...payload,
1774
+ reasoning_effort: "high"
1775
+ };
1776
+ return payload;
1777
+ }
1778
+ function logThinkingInjection(original, injected, resolvedModel) {
1779
+ if (original.reasoning_effort || original.thinking_budget) consola.debug(`Thinking: client-specified (reasoning_effort=${original.reasoning_effort ?? "none"} / thinking_budget=${original.thinking_budget ?? "none"})`);
1780
+ else if (injected.thinking_budget && injected.thinking_budget !== original.thinking_budget) consola.debug(`Thinking: injected thinking_budget=${injected.thinking_budget} for "${resolvedModel}"`);
1781
+ else if (injected.reasoning_effort === "high") consola.debug(`Thinking: injected reasoning_effort=high for "${resolvedModel}"`);
1782
+ else if (reasoningUnsupportedModels.has(resolvedModel)) consola.debug(`Thinking: skipped — "${resolvedModel}" does not support reasoning`);
1783
+ }
1715
1784
  const createChatCompletions = async (payload) => {
1716
1785
  const resolvedModel = modelRouter.resolveModel(payload.model);
1717
1786
  const routedPayload = resolvedModel !== payload.model ? {
@@ -1719,22 +1788,46 @@ const createChatCompletions = async (payload) => {
1719
1788
  model: resolvedModel
1720
1789
  } : payload;
1721
1790
  if (resolvedModel !== payload.model) consola.debug(`Model routed: ${payload.model} → ${resolvedModel}`);
1722
- const supportsReasoning = /^claude-.+-4\.6/.test(resolvedModel);
1723
- const thinkingPayload = {
1724
- ...routedPayload,
1725
- ...!routedPayload.reasoning_effort && supportsReasoning && { reasoning_effort: "high" }
1726
- };
1791
+ const thinkingPayload = injectThinking(routedPayload, resolvedModel);
1792
+ const wasInjected = thinkingPayload.reasoning_effort !== routedPayload.reasoning_effort || thinkingPayload.thinking_budget !== routedPayload.thinking_budget;
1793
+ logThinkingInjection(routedPayload, thinkingPayload, resolvedModel);
1727
1794
  const releaseSlot = await modelRouter.acquireSlot(resolvedModel);
1728
1795
  try {
1729
- const result = state.multiAccountEnabled && accountManager.hasAccounts() ? await createWithMultiAccount(thinkingPayload) : await createWithSingleAccount(thinkingPayload);
1796
+ const result = await dispatchRequest(thinkingPayload);
1730
1797
  if (Symbol.asyncIterator in result) return wrapGeneratorWithRelease(result, releaseSlot);
1731
1798
  releaseSlot();
1732
1799
  return result;
1733
1800
  } catch (error) {
1801
+ if (wasInjected && error instanceof HTTPError && error.response.status === 400 && error.message.includes("Unrecognized request argument")) {
1802
+ reasoningUnsupportedModels.add(resolvedModel);
1803
+ consola.info(`Model "${resolvedModel}" does not support reasoning_effort — disabled for future requests`);
1804
+ return retryWithoutReasoning(routedPayload, releaseSlot);
1805
+ }
1734
1806
  releaseSlot();
1735
1807
  throw error;
1736
1808
  }
1737
1809
  };
1810
+ /**
1811
+ * Retry a request without reasoning_effort after the model rejected it.
1812
+ * Handles slot release for both streaming and non-streaming responses.
1813
+ */
1814
+ async function retryWithoutReasoning(payload, releaseSlot) {
1815
+ try {
1816
+ const result = await dispatchRequest(payload);
1817
+ if (Symbol.asyncIterator in result) return wrapGeneratorWithRelease(result, releaseSlot);
1818
+ releaseSlot();
1819
+ return result;
1820
+ } catch (retryError) {
1821
+ releaseSlot();
1822
+ throw retryError;
1823
+ }
1824
+ }
1825
+ /**
1826
+ * Dispatch request to either single-account or multi-account path.
1827
+ */
1828
+ function dispatchRequest(payload) {
1829
+ return state.multiAccountEnabled && accountManager.hasAccounts() ? createWithMultiAccount(payload) : createWithSingleAccount(payload);
1830
+ }
1738
1831
  async function createWithSingleAccount(payload) {
1739
1832
  if (!state.copilotToken) throw new Error("Copilot token not found");
1740
1833
  const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x) => x.type === "image_url"));
@@ -2246,7 +2339,8 @@ function translateToOpenAI(payload) {
2246
2339
  tools: translateAnthropicToolsToOpenAI(payload.tools),
2247
2340
  tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice),
2248
2341
  ...payload.thinking && { thinking: payload.thinking },
2249
- ...payload.thinking?.type === "enabled" && { reasoning_effort: "high" }
2342
+ ...payload.thinking?.type === "enabled" && { reasoning_effort: "high" },
2343
+ ...payload.thinking?.budget_tokens && { thinking_budget: payload.thinking.budget_tokens }
2250
2344
  };
2251
2345
  }
2252
2346
  function translateModelName(model) {
@@ -2911,7 +3005,7 @@ async function validateGitHubToken(token) {
2911
3005
  state.githubToken = token;
2912
3006
  consola.info("Using provided GitHub token");
2913
3007
  try {
2914
- const { getGitHubUser } = await import("./get-user-D5-qoD5J.js");
3008
+ const { getGitHubUser } = await import("./get-user-BTN_-eOk.js");
2915
3009
  const user = await getGitHubUser();
2916
3010
  consola.info(`Logged in as ${user.login}`);
2917
3011
  } catch (error) {
@@ -2960,7 +3054,7 @@ async function runServer(options) {
2960
3054
  const { HTTPError } = await import("./error-DLqcVQL_.js");
2961
3055
  if (error instanceof HTTPError && error.response.status === 401) {
2962
3056
  consola.error("Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked");
2963
- const { clearGithubToken } = await import("./token-Brc5l1C6.js");
3057
+ const { clearGithubToken } = await import("./token-BsOH3gXZ.js");
2964
3058
  await clearGithubToken();
2965
3059
  consola.info("Please restart to re-authenticate");
2966
3060
  }