@jeffreycao/copilot-api 1.6.7 → 1.6.9

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/dist/main.js CHANGED
@@ -23,7 +23,7 @@ if (typeof args["enterprise-url"] === "string") process.env.COPILOT_API_ENTERPRI
23
23
  const { auth } = await import("./auth-BgOK9NO8.js");
24
24
  const { checkUsage } = await import("./check-usage-B2MnS4b2.js");
25
25
  const { debug } = await import("./debug-DcC7ZPH0.js");
26
- const { start } = await import("./start-BPlrf62e.js");
26
+ const { start } = await import("./start-rMJ6MBo0.js");
27
27
  const main = defineCommand({
28
28
  meta: {
29
29
  name: "copilot-api",
@@ -248,6 +248,52 @@ async function checkRateLimit(state$1) {
248
248
  consola.info("Rate limit wait completed, proceeding with request");
249
249
  }
250
250
 
251
+ //#endregion
252
+ //#region src/lib/copilot-rate-limit.ts
253
+ const copilotRateLimitTypes = ["session", "weekly"];
254
+ const copilotRateLimitHeaders = {
255
+ session: "x-usage-ratelimit-session",
256
+ weekly: "x-usage-ratelimit-weekly"
257
+ };
258
+ const hasGetMethod = (headers) => {
259
+ return "get" in headers && typeof headers.get === "function";
260
+ };
261
+ const getHeaderValue = (headers, headerName) => {
262
+ if (hasGetMethod(headers)) return headers.get(headerName);
263
+ const normalizedHeaderName = headerName.toLowerCase();
264
+ return Object.entries(headers).find(([key]) => key.toLowerCase() === normalizedHeaderName)?.[1] ?? null;
265
+ };
266
+ const parseCopilotRateLimitHeader = (headerValue) => {
267
+ const params = new URLSearchParams(headerValue);
268
+ const remaining = params.get("rem");
269
+ const resetAt = params.get("rst");
270
+ if (!remaining || !resetAt) return null;
271
+ return {
272
+ remaining,
273
+ resetAt
274
+ };
275
+ };
276
+ const getCopilotRateLimitUsage = (headers, type) => {
277
+ const headerName = copilotRateLimitHeaders[type];
278
+ const headerValue = getHeaderValue(headers, headerName);
279
+ if (!headerValue) return null;
280
+ const parsed = parseCopilotRateLimitHeader(headerValue);
281
+ if (!parsed) return null;
282
+ return {
283
+ type,
284
+ ...parsed
285
+ };
286
+ };
287
+ const logCopilotRateLimits = (headers) => {
288
+ for (const type of copilotRateLimitTypes) {
289
+ const usage = getCopilotRateLimitUsage(headers, type);
290
+ if (!usage) continue;
291
+ const d = new Date(usage.resetAt);
292
+ const dateStr = Number.isNaN(d.getTime()) ? usage.resetAt : d.toLocaleString();
293
+ consola.info(`Copilot ${usage.type} quota remaining: ${usage.remaining}, resets at: ${dateStr}`);
294
+ }
295
+ };
296
+
251
297
  //#endregion
252
298
  //#region src/services/copilot/create-chat-completions.ts
253
299
  const createChatCompletions = async (payload, options) => {
@@ -270,6 +316,7 @@ const createChatCompletions = async (payload, options) => {
270
316
  headers,
271
317
  body: JSON.stringify(payload)
272
318
  });
319
+ logCopilotRateLimits(response.headers);
273
320
  if (!response.ok) {
274
321
  consola.error("Failed to create chat completions", response);
275
322
  throw new HTTPError("Failed to create chat completions", response);
@@ -962,6 +1009,7 @@ const createResponses = async (payload, { vision, initiator, subagentMarker, req
962
1009
  headers,
963
1010
  body: JSON.stringify(payload)
964
1011
  });
1012
+ logCopilotRateLimits(response.headers);
965
1013
  if (!response.ok) {
966
1014
  consola.error("Failed to create responses", response);
967
1015
  throw new HTTPError("Failed to create responses", response);
@@ -1947,6 +1995,7 @@ const createMessages = async (payload, anthropicBetaHeader, options) => {
1947
1995
  headers,
1948
1996
  body: JSON.stringify(payload)
1949
1997
  });
1998
+ logCopilotRateLimits(response.headers);
1950
1999
  if (!response.ok) {
1951
2000
  consola.error("Failed to create messages", response);
1952
2001
  throw new HTTPError("Failed to create messages", response);
@@ -2572,6 +2621,8 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
2572
2621
  for await (const event of response) {
2573
2622
  const eventName = event.event;
2574
2623
  const data = event.data ?? "";
2624
+ if (data === "[DONE]") break;
2625
+ if (!data) continue;
2575
2626
  debugLazy(logger$7, () => ["Messages raw stream event:", data]);
2576
2627
  await stream.writeSSE({
2577
2628
  event: eventName,
@@ -3024,6 +3075,7 @@ const handleResponses = async (c) => {
3024
3075
  const sessionId = getUUID(requestId);
3025
3076
  logger$1.debug("Extracted session ID:", sessionId);
3026
3077
  useFunctionApplyPatch(payload);
3078
+ removeUnsupportedTools(payload);
3027
3079
  if (!isResponsesApiWebSearchEnabled()) removeWebSearchTool(payload);
3028
3080
  compactInputByLatestCompaction(payload);
3029
3081
  const selectedModel = state.models?.data.find((model) => model.id === payload.model);
@@ -3095,6 +3147,20 @@ const removeWebSearchTool = (payload) => {
3095
3147
  return t.type !== "web_search";
3096
3148
  });
3097
3149
  };
3150
+ const COPILOT_UNSUPPORTED_TOOL_TYPES = new Set(["image_generation"]);
3151
+ const removeUnsupportedTools = (payload) => {
3152
+ if (!Array.isArray(payload.tools) || payload.tools.length === 0) return;
3153
+ const dropped = [];
3154
+ payload.tools = payload.tools.filter((t) => {
3155
+ const type = t.type;
3156
+ if (COPILOT_UNSUPPORTED_TOOL_TYPES.has(type)) {
3157
+ dropped.push(type);
3158
+ return false;
3159
+ }
3160
+ return true;
3161
+ });
3162
+ if (dropped.length > 0) logger$1.debug("Removed unsupported tools:", dropped);
3163
+ };
3098
3164
 
3099
3165
  //#endregion
3100
3166
  //#region src/routes/responses/route.ts
@@ -3168,4 +3234,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
3168
3234
 
3169
3235
  //#endregion
3170
3236
  export { server };
3171
- //# sourceMappingURL=server-B4dnJhMM.js.map
3237
+ //# sourceMappingURL=server-DzviJdGg.js.map