@hsupu/copilot-api 0.7.14 → 0.7.15

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
@@ -871,6 +871,179 @@ async function initTokenManagers(options = {}) {
871
871
  };
872
872
  }
873
873
 
874
+ //#endregion
875
+ //#region src/lib/tui/tracker.ts
876
+ function generateId$1() {
877
+ return Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
878
+ }
879
+ var RequestTracker = class {
880
+ requests = /* @__PURE__ */ new Map();
881
+ renderer = null;
882
+ completedQueue = [];
883
+ completedTimeouts = /* @__PURE__ */ new Map();
884
+ historySize = 5;
885
+ completedDisplayMs = 2e3;
886
+ setRenderer(renderer$1) {
887
+ this.renderer = renderer$1;
888
+ }
889
+ setOptions(options) {
890
+ if (options.historySize !== void 0) this.historySize = options.historySize;
891
+ if (options.completedDisplayMs !== void 0) this.completedDisplayMs = options.completedDisplayMs;
892
+ }
893
+ /**
894
+ * Start tracking a new request
895
+ * Returns the tracking ID
896
+ */
897
+ startRequest(options) {
898
+ const id = generateId$1();
899
+ const request = {
900
+ id,
901
+ method: options.method,
902
+ path: options.path,
903
+ model: options.model,
904
+ startTime: Date.now(),
905
+ status: "executing",
906
+ isHistoryAccess: options.isHistoryAccess
907
+ };
908
+ this.requests.set(id, request);
909
+ this.renderer?.onRequestStart(request);
910
+ return id;
911
+ }
912
+ /**
913
+ * Update request status
914
+ */
915
+ updateRequest(id, update) {
916
+ const request = this.requests.get(id);
917
+ if (!request) return;
918
+ if (update.status !== void 0) request.status = update.status;
919
+ if (update.statusCode !== void 0) request.statusCode = update.statusCode;
920
+ if (update.durationMs !== void 0) request.durationMs = update.durationMs;
921
+ if (update.inputTokens !== void 0) request.inputTokens = update.inputTokens;
922
+ if (update.outputTokens !== void 0) request.outputTokens = update.outputTokens;
923
+ if (update.error !== void 0) request.error = update.error;
924
+ if (update.queuePosition !== void 0) request.queuePosition = update.queuePosition;
925
+ this.renderer?.onRequestUpdate(id, update);
926
+ }
927
+ /**
928
+ * Mark request as completed
929
+ */
930
+ completeRequest(id, statusCode, usage) {
931
+ const request = this.requests.get(id);
932
+ if (!request) return;
933
+ request.status = statusCode >= 200 && statusCode < 400 ? "completed" : "error";
934
+ request.statusCode = statusCode;
935
+ request.durationMs = Date.now() - request.startTime;
936
+ if (usage) {
937
+ request.inputTokens = usage.inputTokens;
938
+ request.outputTokens = usage.outputTokens;
939
+ }
940
+ this.renderer?.onRequestComplete(request);
941
+ this.requests.delete(id);
942
+ this.completedQueue.push(request);
943
+ while (this.completedQueue.length > this.historySize) {
944
+ const removed = this.completedQueue.shift();
945
+ if (removed) {
946
+ const timeoutId$1 = this.completedTimeouts.get(removed.id);
947
+ if (timeoutId$1) {
948
+ clearTimeout(timeoutId$1);
949
+ this.completedTimeouts.delete(removed.id);
950
+ }
951
+ }
952
+ }
953
+ const timeoutId = setTimeout(() => {
954
+ const idx = this.completedQueue.indexOf(request);
955
+ if (idx !== -1) this.completedQueue.splice(idx, 1);
956
+ this.completedTimeouts.delete(id);
957
+ }, this.completedDisplayMs);
958
+ this.completedTimeouts.set(id, timeoutId);
959
+ }
960
+ /**
961
+ * Mark request as failed with error
962
+ */
963
+ failRequest(id, error) {
964
+ const request = this.requests.get(id);
965
+ if (!request) return;
966
+ request.status = "error";
967
+ request.error = error;
968
+ request.durationMs = Date.now() - request.startTime;
969
+ this.renderer?.onRequestComplete(request);
970
+ this.requests.delete(id);
971
+ this.completedQueue.push(request);
972
+ while (this.completedQueue.length > this.historySize) this.completedQueue.shift();
973
+ }
974
+ /**
975
+ * Get all active requests
976
+ */
977
+ getActiveRequests() {
978
+ return Array.from(this.requests.values());
979
+ }
980
+ /**
981
+ * Get recently completed requests
982
+ */
983
+ getCompletedRequests() {
984
+ return [...this.completedQueue];
985
+ }
986
+ /**
987
+ * Get request by ID
988
+ */
989
+ getRequest(id) {
990
+ return this.requests.get(id);
991
+ }
992
+ /**
993
+ * Clear all tracked requests and pending timeouts
994
+ */
995
+ clear() {
996
+ this.requests.clear();
997
+ this.completedQueue = [];
998
+ for (const timeoutId of this.completedTimeouts.values()) clearTimeout(timeoutId);
999
+ this.completedTimeouts.clear();
1000
+ }
1001
+ };
1002
+ const requestTracker = new RequestTracker();
1003
+
1004
+ //#endregion
1005
+ //#region src/lib/tui/middleware.ts
1006
+ /**
1007
+ * Custom logger middleware that tracks requests through the TUI system
1008
+ * Shows single-line output: METHOD /path 200 1.2s 1.5K/500 model-name
1009
+ *
1010
+ * For streaming responses (SSE), the handler is responsible for calling
1011
+ * completeRequest after the stream finishes.
1012
+ */
1013
+ function tuiLogger() {
1014
+ return async (c, next) => {
1015
+ const method = c.req.method;
1016
+ const path$1 = c.req.path;
1017
+ const isHistoryAccess = path$1.startsWith("/history");
1018
+ const trackingId = requestTracker.startRequest({
1019
+ method,
1020
+ path: path$1,
1021
+ model: "",
1022
+ isHistoryAccess
1023
+ });
1024
+ c.set("trackingId", trackingId);
1025
+ try {
1026
+ await next();
1027
+ if ((c.res.headers.get("content-type") ?? "").includes("text/event-stream")) return;
1028
+ const status = c.res.status;
1029
+ const inputTokens = c.res.headers.get("x-input-tokens");
1030
+ const outputTokens = c.res.headers.get("x-output-tokens");
1031
+ const model = c.res.headers.get("x-model");
1032
+ if (model) {
1033
+ const request = requestTracker.getRequest(trackingId);
1034
+ if (request) request.model = model;
1035
+ }
1036
+ requestTracker.completeRequest(trackingId, status, inputTokens && outputTokens ? {
1037
+ inputTokens: Number.parseInt(inputTokens, 10),
1038
+ outputTokens: Number.parseInt(outputTokens, 10)
1039
+ } : void 0);
1040
+ } catch (error) {
1041
+ requestTracker.failRequest(trackingId, error instanceof Error ? error.message : "Unknown error");
1042
+ throw error;
1043
+ }
1044
+ };
1045
+ }
1046
+
874
1047
  //#endregion
875
1048
  //#region src/lib/logger.ts
876
1049
  /**
@@ -1129,179 +1302,6 @@ var ConsoleRenderer = class {
1129
1302
  }
1130
1303
  };
1131
1304
 
1132
- //#endregion
1133
- //#region src/lib/tui/tracker.ts
1134
- function generateId$1() {
1135
- return Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
1136
- }
1137
- var RequestTracker = class {
1138
- requests = /* @__PURE__ */ new Map();
1139
- renderer = null;
1140
- completedQueue = [];
1141
- completedTimeouts = /* @__PURE__ */ new Map();
1142
- historySize = 5;
1143
- completedDisplayMs = 2e3;
1144
- setRenderer(renderer$1) {
1145
- this.renderer = renderer$1;
1146
- }
1147
- setOptions(options) {
1148
- if (options.historySize !== void 0) this.historySize = options.historySize;
1149
- if (options.completedDisplayMs !== void 0) this.completedDisplayMs = options.completedDisplayMs;
1150
- }
1151
- /**
1152
- * Start tracking a new request
1153
- * Returns the tracking ID
1154
- */
1155
- startRequest(options) {
1156
- const id = generateId$1();
1157
- const request = {
1158
- id,
1159
- method: options.method,
1160
- path: options.path,
1161
- model: options.model,
1162
- startTime: Date.now(),
1163
- status: "executing",
1164
- isHistoryAccess: options.isHistoryAccess
1165
- };
1166
- this.requests.set(id, request);
1167
- this.renderer?.onRequestStart(request);
1168
- return id;
1169
- }
1170
- /**
1171
- * Update request status
1172
- */
1173
- updateRequest(id, update) {
1174
- const request = this.requests.get(id);
1175
- if (!request) return;
1176
- if (update.status !== void 0) request.status = update.status;
1177
- if (update.statusCode !== void 0) request.statusCode = update.statusCode;
1178
- if (update.durationMs !== void 0) request.durationMs = update.durationMs;
1179
- if (update.inputTokens !== void 0) request.inputTokens = update.inputTokens;
1180
- if (update.outputTokens !== void 0) request.outputTokens = update.outputTokens;
1181
- if (update.error !== void 0) request.error = update.error;
1182
- if (update.queuePosition !== void 0) request.queuePosition = update.queuePosition;
1183
- this.renderer?.onRequestUpdate(id, update);
1184
- }
1185
- /**
1186
- * Mark request as completed
1187
- */
1188
- completeRequest(id, statusCode, usage) {
1189
- const request = this.requests.get(id);
1190
- if (!request) return;
1191
- request.status = statusCode >= 200 && statusCode < 400 ? "completed" : "error";
1192
- request.statusCode = statusCode;
1193
- request.durationMs = Date.now() - request.startTime;
1194
- if (usage) {
1195
- request.inputTokens = usage.inputTokens;
1196
- request.outputTokens = usage.outputTokens;
1197
- }
1198
- this.renderer?.onRequestComplete(request);
1199
- this.requests.delete(id);
1200
- this.completedQueue.push(request);
1201
- while (this.completedQueue.length > this.historySize) {
1202
- const removed = this.completedQueue.shift();
1203
- if (removed) {
1204
- const timeoutId$1 = this.completedTimeouts.get(removed.id);
1205
- if (timeoutId$1) {
1206
- clearTimeout(timeoutId$1);
1207
- this.completedTimeouts.delete(removed.id);
1208
- }
1209
- }
1210
- }
1211
- const timeoutId = setTimeout(() => {
1212
- const idx = this.completedQueue.indexOf(request);
1213
- if (idx !== -1) this.completedQueue.splice(idx, 1);
1214
- this.completedTimeouts.delete(id);
1215
- }, this.completedDisplayMs);
1216
- this.completedTimeouts.set(id, timeoutId);
1217
- }
1218
- /**
1219
- * Mark request as failed with error
1220
- */
1221
- failRequest(id, error) {
1222
- const request = this.requests.get(id);
1223
- if (!request) return;
1224
- request.status = "error";
1225
- request.error = error;
1226
- request.durationMs = Date.now() - request.startTime;
1227
- this.renderer?.onRequestComplete(request);
1228
- this.requests.delete(id);
1229
- this.completedQueue.push(request);
1230
- while (this.completedQueue.length > this.historySize) this.completedQueue.shift();
1231
- }
1232
- /**
1233
- * Get all active requests
1234
- */
1235
- getActiveRequests() {
1236
- return Array.from(this.requests.values());
1237
- }
1238
- /**
1239
- * Get recently completed requests
1240
- */
1241
- getCompletedRequests() {
1242
- return [...this.completedQueue];
1243
- }
1244
- /**
1245
- * Get request by ID
1246
- */
1247
- getRequest(id) {
1248
- return this.requests.get(id);
1249
- }
1250
- /**
1251
- * Clear all tracked requests and pending timeouts
1252
- */
1253
- clear() {
1254
- this.requests.clear();
1255
- this.completedQueue = [];
1256
- for (const timeoutId of this.completedTimeouts.values()) clearTimeout(timeoutId);
1257
- this.completedTimeouts.clear();
1258
- }
1259
- };
1260
- const requestTracker = new RequestTracker();
1261
-
1262
- //#endregion
1263
- //#region src/lib/tui/middleware.ts
1264
- /**
1265
- * Custom logger middleware that tracks requests through the TUI system
1266
- * Shows single-line output: METHOD /path 200 1.2s 1.5K/500 model-name
1267
- *
1268
- * For streaming responses (SSE), the handler is responsible for calling
1269
- * completeRequest after the stream finishes.
1270
- */
1271
- function tuiLogger() {
1272
- return async (c, next) => {
1273
- const method = c.req.method;
1274
- const path$1 = c.req.path;
1275
- const isHistoryAccess = path$1.startsWith("/history");
1276
- const trackingId = requestTracker.startRequest({
1277
- method,
1278
- path: path$1,
1279
- model: "",
1280
- isHistoryAccess
1281
- });
1282
- c.set("trackingId", trackingId);
1283
- try {
1284
- await next();
1285
- if ((c.res.headers.get("content-type") ?? "").includes("text/event-stream")) return;
1286
- const status = c.res.status;
1287
- const inputTokens = c.res.headers.get("x-input-tokens");
1288
- const outputTokens = c.res.headers.get("x-output-tokens");
1289
- const model = c.res.headers.get("x-model");
1290
- if (model) {
1291
- const request = requestTracker.getRequest(trackingId);
1292
- if (request) request.model = model;
1293
- }
1294
- requestTracker.completeRequest(trackingId, status, inputTokens && outputTokens ? {
1295
- inputTokens: Number.parseInt(inputTokens, 10),
1296
- outputTokens: Number.parseInt(outputTokens, 10)
1297
- } : void 0);
1298
- } catch (error) {
1299
- requestTracker.failRequest(trackingId, error instanceof Error ? error.message : "Unknown error");
1300
- throw error;
1301
- }
1302
- };
1303
- }
1304
-
1305
1305
  //#endregion
1306
1306
  //#region src/lib/tui/index.ts
1307
1307
  let renderer = null;
@@ -1906,7 +1906,7 @@ const patchClaude = defineCommand({
1906
1906
  //#endregion
1907
1907
  //#region package.json
1908
1908
  var name = "@hsupu/copilot-api";
1909
- var version = "0.7.14";
1909
+ var version = "0.7.15";
1910
1910
  var description = "Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code!";
1911
1911
  var keywords = [
1912
1912
  "proxy",
@@ -7334,7 +7334,7 @@ function formatModelInfo(model) {
7334
7334
  const outputK = formatLimit(limits?.max_output_tokens);
7335
7335
  const features = [model.capabilities?.supports?.tool_calls && "tools", model.preview && "preview"].filter(Boolean).join(", ");
7336
7336
  const featureStr = features ? ` (${features})` : "";
7337
- return ` - ${model.id.length > 30 ? `${model.id.slice(0, 27)}...` : model.id.padEnd(30)} ctx:${contextK.padStart(5)} prps:${promptK.padStart(4)} out:${outputK.padStart(4)}` + featureStr;
7337
+ return ` - ${model.id.length > 30 ? `${model.id.slice(0, 27)}...` : model.id.padEnd(30)} ctx:${contextK.padStart(5)} prp:${promptK.padStart(5)} out:${outputK.padStart(5)}` + featureStr;
7338
7338
  }
7339
7339
  const SECURITY_RESEARCH_SALT = "copilot-api-security-research:";
7340
7340
  const SECURITY_RESEARCH_HASH = "400d6b268f04b9ae9d9ea9b27a93364c3b24565c";
@@ -7394,7 +7394,6 @@ async function setupClaudeCodeConfig(serverUrl, model, smallModel) {
7394
7394
  consola.box(`Claude Code configured!\n\nModel: ${model}\nSmall Model: ${smallModel}\nAPI URL: ${serverUrl}\n\nRun 'claude' to start Claude Code.`);
7395
7395
  }
7396
7396
  async function runServer(options) {
7397
- initConsolaReporter();
7398
7397
  if (options.verbose) {
7399
7398
  consola.level = 5;
7400
7399
  state.verbose = true;
@@ -7601,6 +7600,7 @@ const start = defineCommand({
7601
7600
  }
7602
7601
  },
7603
7602
  run({ args }) {
7603
+ initConsolaReporter();
7604
7604
  const knownArgs = new Set([
7605
7605
  "_",
7606
7606
  "port",
@@ -7610,27 +7610,46 @@ const start = defineCommand({
7610
7610
  "verbose",
7611
7611
  "v",
7612
7612
  "account-type",
7613
+ "accountType",
7613
7614
  "a",
7614
7615
  "manual",
7615
7616
  "no-rate-limit",
7617
+ "noRateLimit",
7616
7618
  "retry-interval",
7619
+ "retryInterval",
7617
7620
  "request-interval",
7621
+ "requestInterval",
7618
7622
  "recovery-timeout",
7623
+ "recoveryTimeout",
7619
7624
  "consecutive-successes",
7625
+ "consecutiveSuccesses",
7620
7626
  "github-token",
7627
+ "githubToken",
7621
7628
  "g",
7622
7629
  "setup-claude-code",
7630
+ "setupClaudeCode",
7623
7631
  "claude-model",
7632
+ "claudeModel",
7624
7633
  "claude-small-model",
7634
+ "claudeSmallModel",
7625
7635
  "show-github-token",
7636
+ "showGithubToken",
7626
7637
  "proxy-env",
7638
+ "proxyEnv",
7627
7639
  "no-history",
7640
+ "noHistory",
7628
7641
  "history-limit",
7642
+ "historyLimit",
7629
7643
  "no-auto-truncate",
7644
+ "noAutoTruncate",
7630
7645
  "compress-tool-results",
7646
+ "compressToolResults",
7631
7647
  "redirect-anthropic",
7648
+ "redirectAnthropic",
7632
7649
  "no-rewrite-anthropic-tools",
7633
- "security-research-mode"
7650
+ "noRewriteAnthropicTools",
7651
+ "security-research-mode",
7652
+ "securityResearchMode"
7634
7653
  ]);
7635
7654
  const unknownArgs = Object.keys(args).filter((key) => !knownArgs.has(key));
7636
7655
  if (unknownArgs.length > 0) consola.warn(`Unknown argument(s): ${unknownArgs.map((a) => `--${a}`).join(", ")}`);