@jeffreycao/copilot-api 1.6.0 → 1.6.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.md CHANGED
@@ -609,7 +609,8 @@ Here is an example `.claude/settings.json` file:
609
609
  },
610
610
  "permissions": {
611
611
  "deny": [
612
- "WebSearch"
612
+ "WebSearch",
613
+ "mcp__ide__executeCode"
613
614
  ]
614
615
  }
615
616
  }
package/README.zh-CN.md CHANGED
@@ -615,7 +615,8 @@ npx @jeffreycao/copilot-api@latest start --claude-code
615
615
  },
616
616
  "permissions": {
617
617
  "deny": [
618
- "WebSearch"
618
+ "WebSearch",
619
+ "mcp__ide__executeCode"
619
620
  ]
620
621
  }
621
622
  }
@@ -1,6 +1,6 @@
1
1
  import { PATHS, ensurePaths } from "./paths-Cla6y5eD.js";
2
- import { state } from "./utils-BWikssll.js";
3
- import { setupGitHubToken } from "./token-DCEVJpKB.js";
2
+ import { state } from "./utils-C_HZ9gNe.js";
3
+ import { setupGitHubToken } from "./token-BINhAFp5.js";
4
4
  import { defineCommand } from "citty";
5
5
  import consola from "consola";
6
6
 
@@ -43,4 +43,4 @@ const auth = defineCommand({
43
43
 
44
44
  //#endregion
45
45
  export { auth };
46
- //# sourceMappingURL=auth-DAlTk9BR.js.map
46
+ //# sourceMappingURL=auth-I-jV5RwF.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-DAlTk9BR.js","names":[],"sources":["../src/auth.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n}\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub auth flow without running the server\",\n },\n args: {\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token on auth\",\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n"],"mappings":";;;;;;;AAcA,eAAsB,QAAQ,SAAwC;AACpE,KAAI,QAAQ,SAAS;AACnB,UAAQ,QAAQ;AAChB,UAAQ,KAAK,0BAA0B;;AAGzC,OAAM,YAAY,QAAQ;AAE1B,OAAM,aAAa;AACnB,OAAM,iBAAiB,EAAE,OAAO,MAAM,CAAC;AACvC,SAAQ,QAAQ,2BAA2B,MAAM,kBAAkB;;AAGrE,MAAa,OAAO,cAAc;CAChC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,SAAS;GACP,OAAO;GACP,MAAM;GACN,SAAS;GACT,aAAa;GACd;EACD,cAAc;GACZ,MAAM;GACN,SAAS;GACT,aAAa;GACd;EACF;CACD,IAAI,EAAE,QAAQ;AACZ,SAAO,QAAQ;GACb,SAAS,KAAK;GACd,WAAW,KAAK;GACjB,CAAC;;CAEL,CAAC"}
1
+ {"version":3,"file":"auth-I-jV5RwF.js","names":[],"sources":["../src/auth.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n}\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub auth flow without running the server\",\n },\n args: {\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token on auth\",\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n"],"mappings":";;;;;;;AAcA,eAAsB,QAAQ,SAAwC;AACpE,KAAI,QAAQ,SAAS;AACnB,UAAQ,QAAQ;AAChB,UAAQ,KAAK,0BAA0B;;AAGzC,OAAM,YAAY,QAAQ;AAE1B,OAAM,aAAa;AACnB,OAAM,iBAAiB,EAAE,OAAO,MAAM,CAAC;AACvC,SAAQ,QAAQ,2BAA2B,MAAM,kBAAkB;;AAGrE,MAAa,OAAO,cAAc;CAChC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,SAAS;GACP,OAAO;GACP,MAAM;GACN,SAAS;GACT,aAAa;GACd;EACD,cAAc;GACZ,MAAM;GACN,SAAS;GACT,aAAa;GACd;EACF;CACD,IAAI,EAAE,QAAQ;AACZ,SAAO,QAAQ;GACb,SAAS,KAAK;GACd,WAAW,KAAK;GACjB,CAAC;;CAEL,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { ensurePaths } from "./paths-Cla6y5eD.js";
2
- import { getCopilotUsage } from "./utils-BWikssll.js";
3
- import { setupGitHubToken } from "./token-DCEVJpKB.js";
2
+ import { getCopilotUsage } from "./utils-C_HZ9gNe.js";
3
+ import { setupGitHubToken } from "./token-BINhAFp5.js";
4
4
  import { defineCommand } from "citty";
5
5
  import consola from "consola";
6
6
 
@@ -41,4 +41,4 @@ const checkUsage = defineCommand({
41
41
 
42
42
  //#endregion
43
43
  export { checkUsage };
44
- //# sourceMappingURL=check-usage-B-1bXEu4.js.map
44
+ //# sourceMappingURL=check-usage-DYLFqYhN.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-usage-B-1bXEu4.js","names":[],"sources":["../src/check-usage.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n"],"mappings":";;;;;;;AAUA,MAAa,aAAa,cAAc;CACtC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,MAAM;AACV,QAAM,aAAa;AACnB,QAAM,kBAAkB;AACxB,MAAI;GACF,MAAM,QAAQ,MAAM,iBAAiB;GACrC,MAAM,UAAU,MAAM,gBAAgB;GACtC,MAAM,eAAe,QAAQ;GAC7B,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,qBACJ,eAAe,IAAK,cAAc,eAAgB,MAAM;GAC1D,MAAM,0BAA0B,QAAQ;GAGxC,SAAS,eAAe,MAAc,MAA+B;AACnE,QAAI,CAAC,KAAM,QAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;AAC9B,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,YAAY,QAAQ,EAAE,CAAC,UAAU,iBAAiB,QAAQ,EAAE,CAAC;;GAGzG,MAAM,cAAc,YAAY,YAAY,GAAG,aAAa,SAAS,mBAAmB,QAAQ,EAAE,CAAC,UAAU,wBAAwB,QAAQ,EAAE,CAAC;GAChJ,MAAM,WAAW,eAAe,QAAQ,MAAM,gBAAgB,KAAK;GACnE,MAAM,kBAAkB,eACtB,eACA,MAAM,gBAAgB,YACvB;AAED,WAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;AACZ,WAAQ,MAAM,kCAAkC,IAAI;AACpD,WAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
1
+ {"version":3,"file":"check-usage-DYLFqYhN.js","names":[],"sources":["../src/check-usage.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n"],"mappings":";;;;;;;AAUA,MAAa,aAAa,cAAc;CACtC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,MAAM;AACV,QAAM,aAAa;AACnB,QAAM,kBAAkB;AACxB,MAAI;GACF,MAAM,QAAQ,MAAM,iBAAiB;GACrC,MAAM,UAAU,MAAM,gBAAgB;GACtC,MAAM,eAAe,QAAQ;GAC7B,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,qBACJ,eAAe,IAAK,cAAc,eAAgB,MAAM;GAC1D,MAAM,0BAA0B,QAAQ;GAGxC,SAAS,eAAe,MAAc,MAA+B;AACnE,QAAI,CAAC,KAAM,QAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;AAC9B,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,YAAY,QAAQ,EAAE,CAAC,UAAU,iBAAiB,QAAQ,EAAE,CAAC;;GAGzG,MAAM,cAAc,YAAY,YAAY,GAAG,aAAa,SAAS,mBAAmB,QAAQ,EAAE,CAAC,UAAU,wBAAwB,QAAQ,EAAE,CAAC;GAChJ,MAAM,WAAW,eAAe,QAAQ,MAAM,gBAAgB,KAAK;GACnE,MAAM,kBAAkB,eACtB,eACA,MAAM,gBAAgB,YACvB;AAED,WAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;AACZ,WAAQ,MAAM,kCAAkC,IAAI;AACpD,WAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
package/dist/main.js CHANGED
@@ -20,10 +20,10 @@ const args = parseArgs(process.argv, cliArgs);
20
20
  if (typeof args["api-home"] === "string") process.env.COPILOT_API_HOME = args["api-home"];
21
21
  if (typeof args["oauth-app"] === "string") process.env.COPILOT_API_OAUTH_APP = args["oauth-app"];
22
22
  if (typeof args["enterprise-url"] === "string") process.env.COPILOT_API_ENTERPRISE_URL = args["enterprise-url"];
23
- const { auth } = await import("./auth-DAlTk9BR.js");
24
- const { checkUsage } = await import("./check-usage-B-1bXEu4.js");
23
+ const { auth } = await import("./auth-I-jV5RwF.js");
24
+ const { checkUsage } = await import("./check-usage-DYLFqYhN.js");
25
25
  const { debug } = await import("./debug-DcC7ZPH0.js");
26
- const { start } = await import("./start-JMKr-2eK.js");
26
+ const { start } = await import("./start-CcPjJUMF.js");
27
27
  const main = defineCommand({
28
28
  meta: {
29
29
  name: "copilot-api",
@@ -1,5 +1,5 @@
1
1
  import { PATHS } from "./paths-Cla6y5eD.js";
2
- import { COMPACT_AUTO_CONTINUE, COMPACT_REQUEST, HTTPError, cacheModels, compactAutoContinuePromptStarts, compactMessageSections, compactSummaryPromptStart, compactSystemPromptStart, compactTextOnlyGuard, copilotBaseUrl, copilotHeaders, forwardError, generateRequestIdFromPayload, getCopilotUsage, getRootSessionId, getUUID, isNullish, parseUserIdMetadata, prepareForCompact, prepareInteractionHeaders, prepareMessageProxyHeaders, requestContext, resolveTraceId, sleep, state } from "./utils-BWikssll.js";
2
+ import { COMPACT_AUTO_CONTINUE, COMPACT_REQUEST, HTTPError, cacheModels, compactAutoContinuePromptStarts, compactMessageSections, compactSummaryPromptStart, compactSystemPromptStart, compactTextOnlyGuard, copilotBaseUrl, copilotHeaders, forwardError, generateRequestIdFromPayload, getCopilotUsage, getRootSessionId, getUUID, isNullish, parseUserIdMetadata, prepareForCompact, prepareInteractionHeaders, prepareMessageProxyHeaders, requestContext, resolveTraceId, sleep, state } from "./utils-C_HZ9gNe.js";
3
3
  import { getAnthropicApiKey, getClaudeTokenMultiplier, getConfig, getExtraPromptForModel, getProviderConfig, getReasoningEffortForModel, getSmallModel, isMessagesApiEnabled, isResponsesApiContextManagementModel, isResponsesApiWebSearchEnabled } from "./config-D44X0MP1.js";
4
4
  import consola from "consola";
5
5
  import path from "node:path";
@@ -1882,11 +1882,21 @@ const allowedAnthropicBetas = new Set([
1882
1882
  "context-management-2025-06-27",
1883
1883
  ADVANCED_TOOL_USE_BETA
1884
1884
  ]);
1885
- const buildAnthropicBetaHeader = (anthropicBetaHeader, thinking) => {
1885
+ const TOOL_SEARCH_SUPPORTED_MODELS = [
1886
+ "claude-sonnet-4.5",
1887
+ "claude-sonnet-4.6",
1888
+ "claude-opus-4.5",
1889
+ "claude-opus-4.6"
1890
+ ];
1891
+ const modelSupportsToolSearch = (modelId) => {
1892
+ return TOOL_SEARCH_SUPPORTED_MODELS.some((prefix) => modelId.toLowerCase().startsWith(prefix));
1893
+ };
1894
+ const buildAnthropicBetaHeader = (anthropicBetaHeader, thinking, model) => {
1886
1895
  const isAdaptiveThinking = thinking?.type === "adaptive";
1887
1896
  if (anthropicBetaHeader) {
1888
1897
  const filteredBeta = anthropicBetaHeader.split(",").map((item) => item.trim()).filter((item) => item.length > 0).filter((item) => allowedAnthropicBetas.has(item));
1889
- const uniqueFilteredBetas = [...new Set([ADVANCED_TOOL_USE_BETA, ...filteredBeta])];
1898
+ const copilotHeaderSet = modelSupportsToolSearch(model) ? [ADVANCED_TOOL_USE_BETA] : [];
1899
+ const uniqueFilteredBetas = [...new Set([...copilotHeaderSet, ...filteredBeta])];
1890
1900
  if (uniqueFilteredBetas.length > 0) return uniqueFilteredBetas.join(",");
1891
1901
  return;
1892
1902
  }
@@ -1909,7 +1919,7 @@ const createMessages = async (payload, anthropicBetaHeader, options) => {
1909
1919
  prepareForCompact(headers, options.compactType);
1910
1920
  const { safetyIdentifier, sessionId } = parseUserIdMetadata(payload.metadata?.user_id);
1911
1921
  if (safetyIdentifier && sessionId) prepareMessageProxyHeaders(headers);
1912
- const anthropicBeta = buildAnthropicBetaHeader(anthropicBetaHeader, payload.thinking);
1922
+ const anthropicBeta = buildAnthropicBetaHeader(anthropicBetaHeader, payload.thinking, payload.model);
1913
1923
  if (anthropicBeta) headers["anthropic-beta"] = anthropicBeta;
1914
1924
  const response = await fetch(`${copilotBaseUrl(state)}/v1/messages`, {
1915
1925
  method: "POST",
@@ -1930,12 +1940,6 @@ const TOOL_REFERENCE_TURN_BOUNDARY = "Tool loaded.";
1930
1940
  const IDE_EXECUTE_CODE_TOOL = "mcp__ide__executeCode";
1931
1941
  const IDE_GET_DIAGNOSTICS_TOOL = "mcp__ide__getDiagnostics";
1932
1942
  const IDE_GET_DIAGNOSTICS_DESCRIPTION = "Get language diagnostics from VS Code. Returns errors, warnings, information, and hints for files in the workspace.";
1933
- const getAnthropicEffortForModel = (model) => {
1934
- const reasoningEffort = getReasoningEffortForModel(model);
1935
- if (reasoningEffort === "xhigh") return "max";
1936
- if (reasoningEffort === "none" || reasoningEffort === "minimal") return "low";
1937
- return reasoningEffort;
1938
- };
1939
1943
  const getCompactCandidateText = (message) => {
1940
1944
  if (message.role !== "user") return "";
1941
1945
  if (typeof message.content === "string") return message.content;
@@ -2054,7 +2058,12 @@ const prepareMessagesApiPayload = (payload, selectedModel) => {
2054
2058
  if (selectedModel?.capabilities.supports.adaptive_thinking && !disableThink) {
2055
2059
  payload.thinking = { type: "adaptive" };
2056
2060
  if (!hasThinking) payload.thinking.display = "summarized";
2057
- payload.output_config = { effort: getAnthropicEffortForModel(payload.model) };
2061
+ if (payload.model === "claude-opus-4.7") payload.thinking.display = "summarized";
2062
+ let effort = getReasoningEffortForModel(payload.model);
2063
+ if (effort === "none" || effort === "minimal") effort = "low";
2064
+ const reasoningEffort = selectedModel.capabilities.supports.reasoning_effort;
2065
+ if (reasoningEffort && !reasoningEffort.includes(effort)) effort = reasoningEffort.at(-1);
2066
+ payload.output_config = { effort };
2058
2067
  }
2059
2068
  };
2060
2069
 
@@ -3026,4 +3035,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
3026
3035
 
3027
3036
  //#endregion
3028
3037
  export { server };
3029
- //# sourceMappingURL=server-DYDw_yEw.js.map
3038
+ //# sourceMappingURL=server-ABtVTO7w.js.map