@nick3/copilot-api 1.0.3 → 1.0.5

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.
@@ -18,8 +18,8 @@
18
18
  }
19
19
  })()
20
20
  </script>
21
- <script type="module" crossorigin src="/admin/assets/index-CFHE7_Zc.js"></script>
22
- <link rel="stylesheet" crossorigin href="/admin/assets/index-DwLAH2FE.css">
21
+ <script type="module" crossorigin src="/admin/assets/index-dN2TC8jw.js"></script>
22
+ <link rel="stylesheet" crossorigin href="/admin/assets/index-BDJkvUef.css">
23
23
  </head>
24
24
  <body>
25
25
  <div id="root"></div>
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { GITHUB_APP_SCOPES, GITHUB_BASE_URL, GITHUB_CLIENT_ID, HTTPError, PATHS, accountsManager, addAccountToRegistry, cacheVSCodeVersion, ensurePaths, getCopilotUsage, getGitHubUser, isFreeModelLoadBalancingEnabled, listAccountsFromRegistry, loadAccountToken, mergeConfigWithDefaults, removeAccountFromRegistry, removeAccountToken, saveAccountToken, saveRegistry, sleep, standardHeaders, state } from "./accounts-manager-CxuKJ4qv.js";
2
+ import { GITHUB_APP_SCOPES, GITHUB_BASE_URL, GITHUB_CLIENT_ID, HTTPError, PATHS, accountsManager, addAccountToRegistry, cacheVSCodeVersion, ensurePaths, getCopilotUsage, getGitHubUser, isFreeModelLoadBalancingEnabled, listAccountsFromRegistry, loadAccountToken, mergeConfigWithDefaults, removeAccountFromRegistry, removeAccountToken, saveAccountToken, saveRegistry, sleep, standardHeaders, state } from "./accounts-manager-wMMW6eow.js";
3
3
  import { defineCommand, runMain } from "citty";
4
4
  import consola from "consola";
5
5
  import fs from "node:fs/promises";
@@ -631,7 +631,7 @@ async function runServer(options) {
631
631
  }
632
632
  }
633
633
  consola.box(`🌐 Usage Viewer: https://ericc-ch.github.io/copilot-api?endpoint=${serverUrl}/usage`);
634
- const { server } = await import("./server-D05YP0C0.js");
634
+ const { server } = await import("./server-Bssp8FSv.js");
635
635
  serve({
636
636
  fetch: server.fetch,
637
637
  port: options.port,
@@ -1,4 +1,4 @@
1
- import { HTTPError, PATHS, accountFromState, accountsManager, copilotBaseUrl, copilotHeaders, forwardError, getAliasTargetSet, getConfig, getCopilotUsage, getExtraPromptForModel, getModelAliases, getReasoningEffortForModel, getSmallModel, isForceAgentEnabled, isFreeModelLoadBalancingEnabled, isNullish, listAccountsFromRegistry, mergeConfigWithDefaults, shouldCompactUseSmallModel, sleep, state } from "./accounts-manager-CxuKJ4qv.js";
1
+ import { HTTPError, PATHS, accountFromState, accountsManager, copilotBaseUrl, copilotHeaders, forwardError, getAliasTargetSet, getConfig, getCopilotUsage, getExtraPromptForModel, getModelAliases, getModelAliasesInfo, getReasoningEffortForModel, getSmallModel, isForceAgentEnabled, isFreeModelLoadBalancingEnabled, isMessageStartInputTokensFallbackEnabled, isNullish, listAccountsFromRegistry, mergeConfigWithDefaults, shouldCompactUseSmallModel, sleep, state } from "./accounts-manager-wMMW6eow.js";
2
2
  import consola from "consola";
3
3
  import fs, { readFile } from "node:fs/promises";
4
4
  import * as path$1 from "node:path";
@@ -714,7 +714,8 @@ const CONFIG_KEYS = new Set([
714
714
  "allowOriginalModelNamesForAliases",
715
715
  "useFunctionApplyPatch",
716
716
  "forceAgent",
717
- "compactUseSmallModel"
717
+ "compactUseSmallModel",
718
+ "messageStartInputTokensFallback"
718
719
  ]);
719
720
  const REASONING_EFFORTS = new Set([
720
721
  "none",
@@ -895,6 +896,9 @@ function applyConfigPatch(base, input) {
895
896
  case "compactUseSmallModel":
896
897
  error = applyOptionalBoolean(next, "compactUseSmallModel", value);
897
898
  break;
899
+ case "messageStartInputTokensFallback":
900
+ error = applyOptionalBoolean(next, "messageStartInputTokensFallback", value);
901
+ break;
898
902
  default: return { error: `Unsupported config key: ${rawKey}` };
899
903
  }
900
904
  if (error) return { error };
@@ -990,6 +994,102 @@ adminApiRoutes.get("/models", (c) => {
990
994
  });
991
995
  }
992
996
  });
997
+ function parseNonEmptyString(value) {
998
+ if (typeof value !== "string") return null;
999
+ const trimmed = value.trim();
1000
+ return trimmed.length > 0 ? trimmed : null;
1001
+ }
1002
+ function parseOptionalFiniteNumber(value) {
1003
+ if (typeof value !== "number") return void 0;
1004
+ return Number.isFinite(value) ? value : void 0;
1005
+ }
1006
+ function toBooleanOrUndefined(value) {
1007
+ return typeof value === "boolean" ? value : void 0;
1008
+ }
1009
+ function parseStringArray(value) {
1010
+ if (!Array.isArray(value)) return void 0;
1011
+ const out = value.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length > 0);
1012
+ return out.length > 0 ? out : void 0;
1013
+ }
1014
+ function parseBilling(value) {
1015
+ if (!isPlainObject(value)) return void 0;
1016
+ const multiplier = parseOptionalFiniteNumber(value.multiplier);
1017
+ const is_premium = toBooleanOrUndefined(value.is_premium);
1018
+ if (multiplier === void 0 && is_premium === void 0) return void 0;
1019
+ return {
1020
+ multiplier,
1021
+ is_premium
1022
+ };
1023
+ }
1024
+ function parseCapabilities(value) {
1025
+ if (!isPlainObject(value)) return {
1026
+ limits: {},
1027
+ supports: {}
1028
+ };
1029
+ const limitsRaw = isPlainObject(value.limits) ? value.limits : void 0;
1030
+ const supportsRaw = isPlainObject(value.supports) ? value.supports : void 0;
1031
+ return {
1032
+ limits: {
1033
+ max_context_window_tokens: parseOptionalFiniteNumber(limitsRaw?.max_context_window_tokens),
1034
+ max_prompt_tokens: parseOptionalFiniteNumber(limitsRaw?.max_prompt_tokens),
1035
+ max_output_tokens: parseOptionalFiniteNumber(limitsRaw?.max_output_tokens)
1036
+ },
1037
+ supports: {
1038
+ tool_calls: toBooleanOrUndefined(supportsRaw?.tool_calls),
1039
+ parallel_tool_calls: toBooleanOrUndefined(supportsRaw?.parallel_tool_calls),
1040
+ structured_outputs: toBooleanOrUndefined(supportsRaw?.structured_outputs),
1041
+ streaming: toBooleanOrUndefined(supportsRaw?.streaming),
1042
+ vision: toBooleanOrUndefined(supportsRaw?.vision)
1043
+ }
1044
+ };
1045
+ }
1046
+ function parseAdminModelDetailsItem(raw, aliasesByTarget) {
1047
+ if (!isPlainObject(raw)) return null;
1048
+ const id = parseNonEmptyString(raw.id);
1049
+ if (!id) return null;
1050
+ const name = parseNonEmptyString(raw.name) ?? id;
1051
+ const preview = toBooleanOrUndefined(raw.preview) ?? false;
1052
+ return {
1053
+ id,
1054
+ name,
1055
+ preview,
1056
+ billing: parseBilling(raw.billing),
1057
+ supported_endpoints: parseStringArray(raw.supported_endpoints),
1058
+ capabilities: parseCapabilities(raw.capabilities),
1059
+ aliases: aliasesByTarget.get(id.toLowerCase()) ?? []
1060
+ };
1061
+ }
1062
+ adminApiRoutes.get("/models/details", (c) => {
1063
+ try {
1064
+ const accountModels = accountsManager.getFirstAccountModels();
1065
+ const aliasInfo = getModelAliasesInfo();
1066
+ const aliasesByTarget = /* @__PURE__ */ new Map();
1067
+ for (const [alias, spec] of Object.entries(aliasInfo)) {
1068
+ const targetKey = spec.target.toLowerCase();
1069
+ const current = aliasesByTarget.get(targetKey);
1070
+ if (current) current.push(alias);
1071
+ else aliasesByTarget.set(targetKey, [alias]);
1072
+ }
1073
+ for (const aliases of aliasesByTarget.values()) aliases.sort();
1074
+ const rawModels = [];
1075
+ if (Array.isArray(accountModels?.data)) rawModels.push(...accountModels.data);
1076
+ const itemsById = /* @__PURE__ */ new Map();
1077
+ for (const raw of rawModels) {
1078
+ const item = parseAdminModelDetailsItem(raw, aliasesByTarget);
1079
+ if (!item) continue;
1080
+ if (itemsById.has(item.id)) continue;
1081
+ itemsById.set(item.id, item);
1082
+ }
1083
+ const items = Array.from(itemsById.values()).sort((a, b) => a.id.localeCompare(b.id));
1084
+ return c.json({ items });
1085
+ } catch (error) {
1086
+ console.error("Failed to load model details.", error);
1087
+ return jsonError(c, 500, {
1088
+ message: "Failed to load model details.",
1089
+ type: "internal_error"
1090
+ });
1091
+ }
1092
+ });
993
1093
  adminApiRoutes.get("/accounts", async (c) => {
994
1094
  const url = new URL(c.req.url, "http://local");
995
1095
  const sinceMs = Number(url.searchParams.get("since_ms") ?? "");
@@ -3151,7 +3251,15 @@ const isWarmupProbeRequest = (payload) => {
3151
3251
  if (!lastMsg || lastMsg.role !== "user" || !Array.isArray(lastMsg.content)) return false;
3152
3252
  const lastBlock = lastMsg.content.at(-1);
3153
3253
  if (!lastBlock || lastBlock.type !== "text") return false;
3154
- return lastBlock.text.trim().toLowerCase() === "warmup" && lastBlock.cache_control?.type === "ephemeral";
3254
+ const text = lastBlock.text.trim().toLowerCase();
3255
+ if (!(lastBlock.cache_control?.type === "ephemeral")) return false;
3256
+ if (text === "warmup") return true;
3257
+ if (text === "hello") {
3258
+ const preludeBlocks = lastMsg.content.slice(0, -1);
3259
+ if (preludeBlocks.length === 0) return false;
3260
+ return preludeBlocks.every((block) => block.type === "text" && block.text.trimStart().toLowerCase().startsWith("<system-reminder"));
3261
+ }
3262
+ return false;
3155
3263
  };
3156
3264
  const handleSelectionFailure = (context) => {
3157
3265
  const { c, store, requestId, startedAtMs, method, path: path$2, streamRequested, clientModel, clientIp, clientIpSource, userAgent, userId, safetyIdentifier, promptCacheKey, initiator, selection } = context;
@@ -3934,7 +4042,8 @@ const createMessages = async (payload, account, options) => {
3934
4042
  ...copilotHeaders(ctx, enableVision, options?.upstreamRequestId),
3935
4043
  "X-Initiator": initiator
3936
4044
  };
3937
- if (options?.anthropicBetaHeader) headers["anthropic-beta"] = options.anthropicBetaHeader;
4045
+ const filteredBeta = options?.anthropicBetaHeader?.split(",").map((item) => item.trim()).filter((item) => item !== "claude-code-20250219").join(",");
4046
+ if (filteredBeta) headers["anthropic-beta"] = filteredBeta;
3938
4047
  else if (payload.thinking?.budget_tokens) headers["anthropic-beta"] = "interleaved-thinking-2025-05-14";
3939
4048
  const response = await fetch(`${copilotBaseUrl(ctx)}/v1/messages`, {
3940
4049
  method: "POST",
@@ -4359,8 +4468,9 @@ const handleWithChatCompletions = async (params) => {
4359
4468
  instr
4360
4469
  });
4361
4470
  logger$2.debug("Streaming response from Copilot");
4362
- const estimatedInputTokens = await estimateInputTokens(openAIPayload, selectedModel, logger$2);
4363
- const historicalUsage = instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
4471
+ const fallbackEnabled = isMessageStartInputTokensFallbackEnabled();
4472
+ const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$2) : void 0;
4473
+ const historicalUsage = fallbackEnabled && instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
4364
4474
  promptCacheKey: instr.promptCacheKey,
4365
4475
  safetyIdentifier: instr.safetyIdentifier,
4366
4476
  clientModel: instr.clientModel
@@ -4398,8 +4508,9 @@ const handleWithResponsesApi = async (params) => {
4398
4508
  }
4399
4509
  if (responsesPayload.stream && isAsyncIterable$1(response)) {
4400
4510
  logger$2.debug("Streaming response from Copilot (Responses API)");
4401
- const estimatedInputTokens = await estimateInputTokens(openAIPayload, selectedModel, logger$2);
4402
- const historicalUsage = instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
4511
+ const fallbackEnabled = isMessageStartInputTokensFallbackEnabled();
4512
+ const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$2) : void 0;
4513
+ const historicalUsage = fallbackEnabled && instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
4403
4514
  promptCacheKey: instr.promptCacheKey,
4404
4515
  safetyIdentifier: instr.safetyIdentifier,
4405
4516
  clientModel: instr.clientModel
@@ -5510,4 +5621,4 @@ server.route("/v1/messages", messageRoutes);
5510
5621
 
5511
5622
  //#endregion
5512
5623
  export { server };
5513
- //# sourceMappingURL=server-D05YP0C0.js.map
5624
+ //# sourceMappingURL=server-Bssp8FSv.js.map