copilot-api-plus 1.0.54 → 1.0.55
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/{auth-BrdL89xk.js → auth-DIDShcrD.js} +10 -5
- package/dist/{auth-BrdL89xk.js.map → auth-DIDShcrD.js.map} +1 -1
- package/dist/{auth-CWGl6kMf.js → auth-D_mymhYC.js} +10 -5
- package/dist/{auth-CWGl6kMf.js.map → auth-D_mymhYC.js.map} +1 -1
- package/dist/auth-DreFwlx2.js +3 -0
- package/dist/auth-g7psLP1B.js +3 -0
- package/dist/error-4DW6q2Mo.js +2 -0
- package/dist/{error-CTmiDu8a.js → error-BYsVGb6T.js} +3 -4
- package/dist/error-BYsVGb6T.js.map +1 -0
- package/dist/{get-models-uEbEgq0L.js → get-models-DhYpjJVG.js} +11 -7
- package/dist/get-models-DhYpjJVG.js.map +1 -0
- package/dist/get-models-PKzVxQmq.js +4 -0
- package/dist/{get-models-DJfPj_Rg.js → get-models-onnSXkNI.js} +8 -4
- package/dist/{get-models-DJfPj_Rg.js.map → get-models-onnSXkNI.js.map} +1 -1
- package/dist/get-user-CtEiwKow.js +3 -0
- package/dist/{get-user-DOjM9pn9.js → get-user-wlP5uMaW.js} +14 -16
- package/dist/get-user-wlP5uMaW.js.map +1 -0
- package/dist/main.js +512 -505
- package/dist/main.js.map +1 -1
- package/dist/{paths-CVYLp61D.js → paths-BdbyVdad.js} +4 -6
- package/dist/{paths-CVYLp61D.js.map → paths-BdbyVdad.js.map} +1 -1
- package/dist/{state-CcLGr8VN.js → state-CRpaW-qc.js} +3 -3
- package/dist/state-CRpaW-qc.js.map +1 -0
- package/dist/token-B_0VZjlS.js +5 -0
- package/dist/{token-CnocHC_C.js → token-Bg5qiNBd.js} +7 -14
- package/dist/token-Bg5qiNBd.js.map +1 -0
- package/package.json +2 -3
- package/dist/auth-BizgZEf2.js +0 -4
- package/dist/auth-pRwfByMF.js +0 -4
- package/dist/error-CBKWgD6B.js +0 -3
- package/dist/error-CTmiDu8a.js.map +0 -1
- package/dist/get-models-COPf69Aa.js +0 -5
- package/dist/get-models-uEbEgq0L.js.map +0 -1
- package/dist/get-user-D1SF4af1.js +0 -5
- package/dist/get-user-DOjM9pn9.js.map +0 -1
- package/dist/state-CcLGr8VN.js.map +0 -1
- package/dist/token-2K-Nf49r.js +0 -7
- package/dist/token-CnocHC_C.js.map +0 -1
package/dist/main.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { state } from "./state-
|
|
4
|
-
import { GITHUB_API_BASE_URL, copilotBaseUrl, copilotHeaders
|
|
5
|
-
import {
|
|
6
|
-
import { cacheModels,
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { n as ensurePaths, t as PATHS } from "./paths-BdbyVdad.js";
|
|
3
|
+
import { t as state } from "./state-CRpaW-qc.js";
|
|
4
|
+
import { c as githubHeaders, n as GITHUB_API_BASE_URL, o as copilotBaseUrl, s as copilotHeaders } from "./get-user-wlP5uMaW.js";
|
|
5
|
+
import { n as forwardError, t as HTTPError } from "./error-BYsVGb6T.js";
|
|
6
|
+
import { a as cacheModels, c as isNullish, i as setupGitHubToken, l as sleep, n as refreshCopilotToken, o as cacheVSCodeVersion, r as setupCopilotToken, s as findModel, t as clearGithubToken } from "./token-Bg5qiNBd.js";
|
|
7
|
+
import { d as getValidAccessToken, g as rotateAccount, l as getCurrentProjectId, n as clearAntigravityAuth, o as getAntigravityAuthPath, r as disableCurrentAccount, s as getApiKey } from "./auth-D_mymhYC.js";
|
|
8
|
+
import { n as getZenAuthPath, t as clearZenAuth } from "./auth-DIDShcrD.js";
|
|
9
|
+
import { n as getAntigravityUsage, r as isThinkingModel, t as getAntigravityModels } from "./get-models-DhYpjJVG.js";
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import { defineCommand, runMain } from "citty";
|
|
12
12
|
import consola from "consola";
|
|
@@ -26,17 +26,12 @@ import { cors } from "hono/cors";
|
|
|
26
26
|
import { HTTPException } from "hono/http-exception";
|
|
27
27
|
import { streamSSE } from "hono/streaming";
|
|
28
28
|
import { events } from "fetch-event-stream";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
32
|
-
var __commonJS = (cb, mod) => function() {
|
|
33
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
34
|
-
};
|
|
29
|
+
//#region \0rolldown/runtime.js
|
|
30
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
35
31
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
36
|
-
|
|
37
32
|
//#endregion
|
|
38
33
|
//#region node_modules/dotenv/package.json
|
|
39
|
-
var require_package = /* @__PURE__ */
|
|
34
|
+
var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
40
35
|
module.exports = {
|
|
41
36
|
"name": "dotenv",
|
|
42
37
|
"version": "17.2.3",
|
|
@@ -95,11 +90,10 @@ var require_package = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/package.
|
|
|
95
90
|
"engines": { "node": ">=12" },
|
|
96
91
|
"browser": { "fs": false }
|
|
97
92
|
};
|
|
98
|
-
})
|
|
99
|
-
|
|
93
|
+
}));
|
|
100
94
|
//#endregion
|
|
101
95
|
//#region node_modules/dotenv/lib/main.js
|
|
102
|
-
var require_main = /* @__PURE__ */
|
|
96
|
+
var require_main = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
103
97
|
const fs$1 = __require("fs");
|
|
104
98
|
const path$1 = __require("path");
|
|
105
99
|
const os$1 = __require("os");
|
|
@@ -162,22 +156,21 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
162
156
|
}
|
|
163
157
|
return obj;
|
|
164
158
|
}
|
|
165
|
-
function _parseVault(options
|
|
166
|
-
options
|
|
167
|
-
const vaultPath = _vaultPath(options
|
|
168
|
-
options
|
|
169
|
-
const result = DotenvModule.configDotenv(options
|
|
159
|
+
function _parseVault(options) {
|
|
160
|
+
options = options || {};
|
|
161
|
+
const vaultPath = _vaultPath(options);
|
|
162
|
+
options.path = vaultPath;
|
|
163
|
+
const result = DotenvModule.configDotenv(options);
|
|
170
164
|
if (!result.parsed) {
|
|
171
165
|
const err = /* @__PURE__ */ new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
172
166
|
err.code = "MISSING_DATA";
|
|
173
167
|
throw err;
|
|
174
168
|
}
|
|
175
|
-
const keys = _dotenvKey(options
|
|
169
|
+
const keys = _dotenvKey(options).split(",");
|
|
176
170
|
const length = keys.length;
|
|
177
171
|
let decrypted;
|
|
178
172
|
for (let i = 0; i < length; i++) try {
|
|
179
|
-
const
|
|
180
|
-
const attrs = _instructions(result, key);
|
|
173
|
+
const attrs = _instructions(result, keys[i].trim());
|
|
181
174
|
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
182
175
|
break;
|
|
183
176
|
} catch (error) {
|
|
@@ -194,8 +187,8 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
194
187
|
function _log(message) {
|
|
195
188
|
console.log(`[dotenv@${version}] ${message}`);
|
|
196
189
|
}
|
|
197
|
-
function _dotenvKey(options
|
|
198
|
-
if (options
|
|
190
|
+
function _dotenvKey(options) {
|
|
191
|
+
if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) return options.DOTENV_KEY;
|
|
199
192
|
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) return process.env.DOTENV_KEY;
|
|
200
193
|
return "";
|
|
201
194
|
}
|
|
@@ -235,11 +228,11 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
235
228
|
key
|
|
236
229
|
};
|
|
237
230
|
}
|
|
238
|
-
function _vaultPath(options
|
|
231
|
+
function _vaultPath(options) {
|
|
239
232
|
let possibleVaultPath = null;
|
|
240
|
-
if (options
|
|
241
|
-
for (const filepath of options
|
|
242
|
-
} else possibleVaultPath = options
|
|
233
|
+
if (options && options.path && options.path.length > 0) if (Array.isArray(options.path)) {
|
|
234
|
+
for (const filepath of options.path) if (fs$1.existsSync(filepath)) possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
235
|
+
} else possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
243
236
|
else possibleVaultPath = path$1.resolve(process.cwd(), ".env.vault");
|
|
244
237
|
if (fs$1.existsSync(possibleVaultPath)) return possibleVaultPath;
|
|
245
238
|
return null;
|
|
@@ -247,51 +240,51 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
247
240
|
function _resolveHome(envPath) {
|
|
248
241
|
return envPath[0] === "~" ? path$1.join(os$1.homedir(), envPath.slice(1)) : envPath;
|
|
249
242
|
}
|
|
250
|
-
function _configVault(options
|
|
251
|
-
const debug
|
|
252
|
-
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options
|
|
253
|
-
if (debug
|
|
254
|
-
const parsed = DotenvModule._parseVault(options
|
|
243
|
+
function _configVault(options) {
|
|
244
|
+
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
245
|
+
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
246
|
+
if (debug || !quiet) _log("Loading env from encrypted .env.vault");
|
|
247
|
+
const parsed = DotenvModule._parseVault(options);
|
|
255
248
|
let processEnv = process.env;
|
|
256
|
-
if (options
|
|
257
|
-
DotenvModule.populate(processEnv, parsed, options
|
|
249
|
+
if (options && options.processEnv != null) processEnv = options.processEnv;
|
|
250
|
+
DotenvModule.populate(processEnv, parsed, options);
|
|
258
251
|
return { parsed };
|
|
259
252
|
}
|
|
260
|
-
function configDotenv(options
|
|
253
|
+
function configDotenv(options) {
|
|
261
254
|
const dotenvPath = path$1.resolve(process.cwd(), ".env");
|
|
262
255
|
let encoding = "utf8";
|
|
263
256
|
let processEnv = process.env;
|
|
264
|
-
if (options
|
|
265
|
-
let debug
|
|
266
|
-
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options
|
|
267
|
-
if (options
|
|
268
|
-
else if (debug
|
|
257
|
+
if (options && options.processEnv != null) processEnv = options.processEnv;
|
|
258
|
+
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
259
|
+
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
260
|
+
if (options && options.encoding) encoding = options.encoding;
|
|
261
|
+
else if (debug) _debug("No encoding is specified. UTF-8 is used by default");
|
|
269
262
|
let optionPaths = [dotenvPath];
|
|
270
|
-
if (options
|
|
263
|
+
if (options && options.path) if (!Array.isArray(options.path)) optionPaths = [_resolveHome(options.path)];
|
|
271
264
|
else {
|
|
272
265
|
optionPaths = [];
|
|
273
|
-
for (const filepath of options
|
|
266
|
+
for (const filepath of options.path) optionPaths.push(_resolveHome(filepath));
|
|
274
267
|
}
|
|
275
268
|
let lastError;
|
|
276
269
|
const parsedAll = {};
|
|
277
|
-
for (const path
|
|
278
|
-
const parsed = DotenvModule.parse(fs$1.readFileSync(path
|
|
279
|
-
DotenvModule.populate(parsedAll, parsed, options
|
|
270
|
+
for (const path of optionPaths) try {
|
|
271
|
+
const parsed = DotenvModule.parse(fs$1.readFileSync(path, { encoding }));
|
|
272
|
+
DotenvModule.populate(parsedAll, parsed, options);
|
|
280
273
|
} catch (e) {
|
|
281
|
-
if (debug
|
|
274
|
+
if (debug) _debug(`Failed to load ${path} ${e.message}`);
|
|
282
275
|
lastError = e;
|
|
283
276
|
}
|
|
284
|
-
const populated = DotenvModule.populate(processEnv, parsedAll, options
|
|
285
|
-
debug
|
|
277
|
+
const populated = DotenvModule.populate(processEnv, parsedAll, options);
|
|
278
|
+
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
|
|
286
279
|
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
|
|
287
|
-
if (debug
|
|
280
|
+
if (debug || !quiet) {
|
|
288
281
|
const keysCount = Object.keys(populated).length;
|
|
289
282
|
const shortPaths = [];
|
|
290
283
|
for (const filePath of optionPaths) try {
|
|
291
284
|
const relative = path$1.relative(process.cwd(), filePath);
|
|
292
285
|
shortPaths.push(relative);
|
|
293
286
|
} catch (e) {
|
|
294
|
-
if (debug
|
|
287
|
+
if (debug) _debug(`Failed to load ${filePath} ${e.message}`);
|
|
295
288
|
lastError = e;
|
|
296
289
|
}
|
|
297
290
|
_log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
|
|
@@ -302,14 +295,14 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
302
295
|
};
|
|
303
296
|
else return { parsed: parsedAll };
|
|
304
297
|
}
|
|
305
|
-
function config(options
|
|
306
|
-
if (_dotenvKey(options
|
|
307
|
-
const vaultPath = _vaultPath(options
|
|
298
|
+
function config(options) {
|
|
299
|
+
if (_dotenvKey(options).length === 0) return DotenvModule.configDotenv(options);
|
|
300
|
+
const vaultPath = _vaultPath(options);
|
|
308
301
|
if (!vaultPath) {
|
|
309
302
|
_warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
|
|
310
|
-
return DotenvModule.configDotenv(options
|
|
303
|
+
return DotenvModule.configDotenv(options);
|
|
311
304
|
}
|
|
312
|
-
return DotenvModule._configVault(options
|
|
305
|
+
return DotenvModule._configVault(options);
|
|
313
306
|
}
|
|
314
307
|
function decrypt(encrypted, keyStr) {
|
|
315
308
|
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
@@ -336,9 +329,9 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
336
329
|
} else throw error;
|
|
337
330
|
}
|
|
338
331
|
}
|
|
339
|
-
function populate(processEnv, parsed, options
|
|
340
|
-
const debug
|
|
341
|
-
const override = Boolean(options
|
|
332
|
+
function populate(processEnv, parsed, options = {}) {
|
|
333
|
+
const debug = Boolean(options && options.debug);
|
|
334
|
+
const override = Boolean(options && options.override);
|
|
342
335
|
const populated = {};
|
|
343
336
|
if (typeof parsed !== "object") {
|
|
344
337
|
const err = /* @__PURE__ */ new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
@@ -350,7 +343,7 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
350
343
|
processEnv[key] = parsed[key];
|
|
351
344
|
populated[key] = parsed[key];
|
|
352
345
|
}
|
|
353
|
-
if (debug
|
|
346
|
+
if (debug) if (override === true) _debug(`"${key}" is already defined and WAS overwritten`);
|
|
354
347
|
else _debug(`"${key}" is already defined and was NOT overwritten`);
|
|
355
348
|
} else {
|
|
356
349
|
processEnv[key] = parsed[key];
|
|
@@ -375,11 +368,10 @@ var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js
|
|
|
375
368
|
module.exports.parse = DotenvModule.parse;
|
|
376
369
|
module.exports.populate = DotenvModule.populate;
|
|
377
370
|
module.exports = DotenvModule;
|
|
378
|
-
})
|
|
379
|
-
|
|
371
|
+
}));
|
|
380
372
|
//#endregion
|
|
381
373
|
//#region node_modules/dotenv/lib/env-options.js
|
|
382
|
-
var require_env_options = /* @__PURE__ */
|
|
374
|
+
var require_env_options = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
383
375
|
const options = {};
|
|
384
376
|
if (process.env.DOTENV_CONFIG_ENCODING != null) options.encoding = process.env.DOTENV_CONFIG_ENCODING;
|
|
385
377
|
if (process.env.DOTENV_CONFIG_PATH != null) options.path = process.env.DOTENV_CONFIG_PATH;
|
|
@@ -388,31 +380,32 @@ var require_env_options = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/
|
|
|
388
380
|
if (process.env.DOTENV_CONFIG_OVERRIDE != null) options.override = process.env.DOTENV_CONFIG_OVERRIDE;
|
|
389
381
|
if (process.env.DOTENV_CONFIG_DOTENV_KEY != null) options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY;
|
|
390
382
|
module.exports = options;
|
|
391
|
-
})
|
|
392
|
-
|
|
383
|
+
}));
|
|
393
384
|
//#endregion
|
|
394
385
|
//#region node_modules/dotenv/lib/cli-options.js
|
|
395
|
-
var require_cli_options = /* @__PURE__ */
|
|
386
|
+
var require_cli_options = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
396
387
|
const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/;
|
|
397
388
|
module.exports = function optionMatcher(args) {
|
|
398
|
-
const options
|
|
389
|
+
const options = args.reduce(function(acc, cur) {
|
|
399
390
|
const matches = cur.match(re);
|
|
400
391
|
if (matches) acc[matches[1]] = matches[2];
|
|
401
392
|
return acc;
|
|
402
393
|
}, {});
|
|
403
|
-
if (!("quiet" in options
|
|
404
|
-
return options
|
|
394
|
+
if (!("quiet" in options)) options.quiet = "true";
|
|
395
|
+
return options;
|
|
405
396
|
};
|
|
406
|
-
})
|
|
407
|
-
|
|
397
|
+
}));
|
|
408
398
|
//#endregion
|
|
409
399
|
//#region node_modules/dotenv/config.js
|
|
410
400
|
(function() {
|
|
411
401
|
require_main().config(Object.assign({}, require_env_options(), require_cli_options()(process.argv)));
|
|
412
402
|
})();
|
|
413
|
-
|
|
414
403
|
//#endregion
|
|
415
404
|
//#region src/lib/config.ts
|
|
405
|
+
/**
|
|
406
|
+
* Configuration file management
|
|
407
|
+
* Handles persistent configuration storage for proxy settings and other options
|
|
408
|
+
*/
|
|
416
409
|
const CONFIG_FILENAME = "config.json";
|
|
417
410
|
/**
|
|
418
411
|
* Get the path to the config file
|
|
@@ -435,9 +428,9 @@ async function loadConfig() {
|
|
|
435
428
|
/**
|
|
436
429
|
* Save configuration to file
|
|
437
430
|
*/
|
|
438
|
-
async function saveConfig(config
|
|
431
|
+
async function saveConfig(config) {
|
|
439
432
|
const configPath = getConfigPath();
|
|
440
|
-
await fs.writeFile(configPath, JSON.stringify(config
|
|
433
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf8");
|
|
441
434
|
consola.debug(`Configuration saved to ${configPath}`);
|
|
442
435
|
}
|
|
443
436
|
/**
|
|
@@ -450,17 +443,17 @@ async function getProxyConfig() {
|
|
|
450
443
|
* Save proxy configuration
|
|
451
444
|
*/
|
|
452
445
|
async function saveProxyConfig(proxyConfig) {
|
|
453
|
-
const config
|
|
454
|
-
config
|
|
455
|
-
await saveConfig(config
|
|
446
|
+
const config = await loadConfig();
|
|
447
|
+
config.proxy = proxyConfig;
|
|
448
|
+
await saveConfig(config);
|
|
456
449
|
}
|
|
457
450
|
/**
|
|
458
451
|
* Clear proxy configuration
|
|
459
452
|
*/
|
|
460
453
|
async function clearProxyConfig() {
|
|
461
|
-
const config
|
|
462
|
-
delete config
|
|
463
|
-
await saveConfig(config
|
|
454
|
+
const config = await loadConfig();
|
|
455
|
+
delete config.proxy;
|
|
456
|
+
await saveConfig(config);
|
|
464
457
|
}
|
|
465
458
|
/**
|
|
466
459
|
* Apply saved proxy configuration to environment variables
|
|
@@ -487,7 +480,6 @@ async function applyProxyConfig() {
|
|
|
487
480
|
if (proxyConfig.noProxy) consola.info(` NO_PROXY: ${proxyConfig.noProxy}`);
|
|
488
481
|
return true;
|
|
489
482
|
}
|
|
490
|
-
|
|
491
483
|
//#endregion
|
|
492
484
|
//#region src/lib/proxy.ts
|
|
493
485
|
function initProxyFromEnv() {
|
|
@@ -496,14 +488,14 @@ function initProxyFromEnv() {
|
|
|
496
488
|
const direct = new Agent();
|
|
497
489
|
const proxies = /* @__PURE__ */ new Map();
|
|
498
490
|
setGlobalDispatcher({
|
|
499
|
-
dispatch(options
|
|
491
|
+
dispatch(options, handler) {
|
|
500
492
|
try {
|
|
501
|
-
const origin = typeof options
|
|
493
|
+
const origin = typeof options.origin === "string" ? new URL(options.origin) : options.origin;
|
|
502
494
|
const raw = getProxyForUrl(origin.toString());
|
|
503
495
|
const proxyUrl = raw && raw.length > 0 ? raw : void 0;
|
|
504
496
|
if (!proxyUrl) {
|
|
505
497
|
consola.debug(`HTTP proxy bypass: ${origin.hostname}`);
|
|
506
|
-
return direct.dispatch(options
|
|
498
|
+
return direct.dispatch(options, handler);
|
|
507
499
|
}
|
|
508
500
|
let agent = proxies.get(proxyUrl);
|
|
509
501
|
if (!agent) {
|
|
@@ -516,9 +508,9 @@ function initProxyFromEnv() {
|
|
|
516
508
|
label = `${u.protocol}//${u.host}`;
|
|
517
509
|
} catch {}
|
|
518
510
|
consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`);
|
|
519
|
-
return agent.dispatch(options
|
|
511
|
+
return agent.dispatch(options, handler);
|
|
520
512
|
} catch {
|
|
521
|
-
return direct.dispatch(options
|
|
513
|
+
return direct.dispatch(options, handler);
|
|
522
514
|
}
|
|
523
515
|
},
|
|
524
516
|
close() {
|
|
@@ -533,14 +525,13 @@ function initProxyFromEnv() {
|
|
|
533
525
|
consola.debug("Proxy setup skipped:", err);
|
|
534
526
|
}
|
|
535
527
|
}
|
|
536
|
-
|
|
537
528
|
//#endregion
|
|
538
529
|
//#region src/antigravity.ts
|
|
539
530
|
/**
|
|
540
531
|
* Add a new Antigravity account via OAuth
|
|
541
532
|
*/
|
|
542
533
|
async function addAccount() {
|
|
543
|
-
const { setupAntigravity, loadAntigravityAuth } = await import("./auth-
|
|
534
|
+
const { setupAntigravity, loadAntigravityAuth } = await import("./auth-DreFwlx2.js");
|
|
544
535
|
const existingAuth = await loadAntigravityAuth();
|
|
545
536
|
if (existingAuth && existingAuth.accounts.length > 0) {
|
|
546
537
|
const enabledCount = existingAuth.accounts.filter((a) => a.enable).length;
|
|
@@ -552,17 +543,17 @@ async function addAccount() {
|
|
|
552
543
|
* List all Antigravity accounts
|
|
553
544
|
*/
|
|
554
545
|
async function listAccounts() {
|
|
555
|
-
const { loadAntigravityAuth } = await import("./auth-
|
|
556
|
-
const auth
|
|
557
|
-
if (!auth
|
|
546
|
+
const { loadAntigravityAuth } = await import("./auth-DreFwlx2.js");
|
|
547
|
+
const auth = await loadAntigravityAuth();
|
|
548
|
+
if (!auth || auth.accounts.length === 0) {
|
|
558
549
|
consola.info("No Antigravity accounts configured");
|
|
559
550
|
return;
|
|
560
551
|
}
|
|
561
|
-
consola.info(`\nAntigravity Accounts (${auth
|
|
552
|
+
consola.info(`\nAntigravity Accounts (${auth.accounts.length} total):`);
|
|
562
553
|
consola.info("=".repeat(50));
|
|
563
|
-
for (let i = 0; i < auth
|
|
564
|
-
const account = auth
|
|
565
|
-
const isCurrent = i === auth
|
|
554
|
+
for (let i = 0; i < auth.accounts.length; i++) {
|
|
555
|
+
const account = auth.accounts[i];
|
|
556
|
+
const isCurrent = i === auth.currentIndex;
|
|
566
557
|
const status = account.enable ? "enabled" : "disabled";
|
|
567
558
|
const marker = isCurrent ? "→ " : " ";
|
|
568
559
|
const projectId = account.project_id || "unknown";
|
|
@@ -573,30 +564,30 @@ async function listAccounts() {
|
|
|
573
564
|
* Remove an Antigravity account by index
|
|
574
565
|
*/
|
|
575
566
|
async function removeAccount(index) {
|
|
576
|
-
const { loadAntigravityAuth, saveAntigravityAuth } = await import("./auth-
|
|
577
|
-
const auth
|
|
578
|
-
if (!auth
|
|
567
|
+
const { loadAntigravityAuth, saveAntigravityAuth } = await import("./auth-DreFwlx2.js");
|
|
568
|
+
const auth = await loadAntigravityAuth();
|
|
569
|
+
if (!auth || auth.accounts.length === 0) {
|
|
579
570
|
consola.error("No Antigravity accounts configured");
|
|
580
571
|
return;
|
|
581
572
|
}
|
|
582
|
-
if (index < 0 || index >= auth
|
|
583
|
-
consola.error(`Invalid index. Must be between 0 and ${auth
|
|
573
|
+
if (index < 0 || index >= auth.accounts.length) {
|
|
574
|
+
consola.error(`Invalid index. Must be between 0 and ${auth.accounts.length - 1}`);
|
|
584
575
|
return;
|
|
585
576
|
}
|
|
586
|
-
const removed = auth
|
|
587
|
-
if (auth
|
|
588
|
-
await saveAntigravityAuth(auth
|
|
577
|
+
const removed = auth.accounts.splice(index, 1)[0];
|
|
578
|
+
if (auth.currentIndex >= auth.accounts.length) auth.currentIndex = Math.max(0, auth.accounts.length - 1);
|
|
579
|
+
await saveAntigravityAuth(auth);
|
|
589
580
|
consola.success(`Removed account ${index} (Project: ${removed.project_id || "unknown"})`);
|
|
590
581
|
}
|
|
591
582
|
/**
|
|
592
583
|
* Clear all Antigravity accounts
|
|
593
584
|
*/
|
|
594
585
|
async function clearAccounts() {
|
|
595
|
-
const { clearAntigravityAuth
|
|
586
|
+
const { clearAntigravityAuth } = await import("./auth-DreFwlx2.js");
|
|
596
587
|
if (await consola.prompt("Are you sure you want to remove all Antigravity accounts?", {
|
|
597
588
|
type: "confirm",
|
|
598
589
|
initial: false
|
|
599
|
-
})) await clearAntigravityAuth
|
|
590
|
+
})) await clearAntigravityAuth();
|
|
600
591
|
}
|
|
601
592
|
const antigravity = defineCommand({
|
|
602
593
|
meta: {
|
|
@@ -658,15 +649,14 @@ const antigravity = defineCommand({
|
|
|
658
649
|
})
|
|
659
650
|
}
|
|
660
651
|
});
|
|
661
|
-
|
|
662
652
|
//#endregion
|
|
663
653
|
//#region src/auth.ts
|
|
664
|
-
async function runAuth(options
|
|
665
|
-
if (options
|
|
654
|
+
async function runAuth(options) {
|
|
655
|
+
if (options.verbose) {
|
|
666
656
|
consola.level = 5;
|
|
667
657
|
consola.info("Verbose logging enabled");
|
|
668
658
|
}
|
|
669
|
-
state.showToken = options
|
|
659
|
+
state.showToken = options.showToken;
|
|
670
660
|
await ensurePaths();
|
|
671
661
|
await setupGitHubToken({ force: true });
|
|
672
662
|
consola.success("GitHub token written to", PATHS.GITHUB_TOKEN_PATH);
|
|
@@ -696,7 +686,6 @@ const auth = defineCommand({
|
|
|
696
686
|
});
|
|
697
687
|
}
|
|
698
688
|
});
|
|
699
|
-
|
|
700
689
|
//#endregion
|
|
701
690
|
//#region src/services/github/get-copilot-usage.ts
|
|
702
691
|
const getCopilotUsage = async () => {
|
|
@@ -704,7 +693,6 @@ const getCopilotUsage = async () => {
|
|
|
704
693
|
if (!response.ok) throw new HTTPError("Failed to get Copilot usage", response);
|
|
705
694
|
return await response.json();
|
|
706
695
|
};
|
|
707
|
-
|
|
708
696
|
//#endregion
|
|
709
697
|
//#region src/check-usage.ts
|
|
710
698
|
const checkUsage = defineCommand({
|
|
@@ -740,7 +728,6 @@ const checkUsage = defineCommand({
|
|
|
740
728
|
}
|
|
741
729
|
}
|
|
742
730
|
});
|
|
743
|
-
|
|
744
731
|
//#endregion
|
|
745
732
|
//#region src/debug.ts
|
|
746
733
|
async function getPackageVersion() {
|
|
@@ -768,10 +755,10 @@ async function checkTokenExists() {
|
|
|
768
755
|
return false;
|
|
769
756
|
}
|
|
770
757
|
}
|
|
771
|
-
async function checkFileExists(path
|
|
758
|
+
async function checkFileExists(path) {
|
|
772
759
|
try {
|
|
773
|
-
if (!(await fs.stat(path
|
|
774
|
-
return (await fs.readFile(path
|
|
760
|
+
if (!(await fs.stat(path)).isFile()) return false;
|
|
761
|
+
return (await fs.readFile(path, "utf8")).trim().length > 0;
|
|
775
762
|
} catch {
|
|
776
763
|
return false;
|
|
777
764
|
}
|
|
@@ -779,7 +766,7 @@ async function checkFileExists(path$2) {
|
|
|
779
766
|
async function getDebugInfo() {
|
|
780
767
|
const zenAuthPath = getZenAuthPath();
|
|
781
768
|
const antigravityAuthPath = getAntigravityAuthPath();
|
|
782
|
-
const [version
|
|
769
|
+
const [version, githubExists, zenExists, antigravityExists, proxyConfig] = await Promise.all([
|
|
783
770
|
getPackageVersion(),
|
|
784
771
|
checkTokenExists(),
|
|
785
772
|
checkFileExists(zenAuthPath),
|
|
@@ -787,7 +774,7 @@ async function getDebugInfo() {
|
|
|
787
774
|
getProxyConfig()
|
|
788
775
|
]);
|
|
789
776
|
return {
|
|
790
|
-
version
|
|
777
|
+
version,
|
|
791
778
|
runtime: getRuntimeInfo(),
|
|
792
779
|
paths: {
|
|
793
780
|
APP_DIR: PATHS.APP_DIR,
|
|
@@ -827,9 +814,9 @@ Proxy: ${proxyStatus}`);
|
|
|
827
814
|
function printDebugInfoJson(info) {
|
|
828
815
|
console.log(JSON.stringify(info, null, 2));
|
|
829
816
|
}
|
|
830
|
-
async function runDebug(options
|
|
817
|
+
async function runDebug(options) {
|
|
831
818
|
const debugInfo = await getDebugInfo();
|
|
832
|
-
if (options
|
|
819
|
+
if (options.json) printDebugInfoJson(debugInfo);
|
|
833
820
|
else printDebugInfoPlain(debugInfo);
|
|
834
821
|
}
|
|
835
822
|
const debug = defineCommand({
|
|
@@ -846,12 +833,11 @@ const debug = defineCommand({
|
|
|
846
833
|
return runDebug({ json: args.json });
|
|
847
834
|
}
|
|
848
835
|
});
|
|
849
|
-
|
|
850
836
|
//#endregion
|
|
851
837
|
//#region src/logout.ts
|
|
852
|
-
async function runLogout(options
|
|
838
|
+
async function runLogout(options) {
|
|
853
839
|
await ensurePaths();
|
|
854
|
-
if (options
|
|
840
|
+
if (options.all) {
|
|
855
841
|
await clearGithubToken();
|
|
856
842
|
await clearZenAuth();
|
|
857
843
|
await clearAntigravityAuth();
|
|
@@ -861,19 +847,19 @@ async function runLogout(options$1) {
|
|
|
861
847
|
consola.info(`Antigravity accounts: ${getAntigravityAuthPath()}`);
|
|
862
848
|
return;
|
|
863
849
|
}
|
|
864
|
-
if (options
|
|
850
|
+
if (options.github) {
|
|
865
851
|
await clearGithubToken();
|
|
866
852
|
consola.success("Logged out from GitHub Copilot");
|
|
867
853
|
consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
868
854
|
return;
|
|
869
855
|
}
|
|
870
|
-
if (options
|
|
856
|
+
if (options.zen) {
|
|
871
857
|
await clearZenAuth();
|
|
872
858
|
consola.success("Logged out from OpenCode Zen");
|
|
873
859
|
consola.info(`Zen API key location: ${getZenAuthPath()}`);
|
|
874
860
|
return;
|
|
875
861
|
}
|
|
876
|
-
if (options
|
|
862
|
+
if (options.antigravity) {
|
|
877
863
|
await clearAntigravityAuth();
|
|
878
864
|
consola.success("Logged out from Google Antigravity");
|
|
879
865
|
consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`);
|
|
@@ -950,9 +936,12 @@ const logout = defineCommand({
|
|
|
950
936
|
});
|
|
951
937
|
}
|
|
952
938
|
});
|
|
953
|
-
|
|
954
939
|
//#endregion
|
|
955
940
|
//#region src/proxy-config.ts
|
|
941
|
+
/**
|
|
942
|
+
* Proxy configuration command
|
|
943
|
+
* Allows users to configure, enable, disable, and view proxy settings
|
|
944
|
+
*/
|
|
956
945
|
const proxy = defineCommand({
|
|
957
946
|
meta: {
|
|
958
947
|
name: "proxy",
|
|
@@ -1000,8 +989,8 @@ const proxy = defineCommand({
|
|
|
1000
989
|
async run({ args }) {
|
|
1001
990
|
await ensurePaths();
|
|
1002
991
|
if (args.show || !args.set && !args.enable && !args.disable && !args.clear && !args["http-proxy"] && !args["https-proxy"]) {
|
|
1003
|
-
const config
|
|
1004
|
-
if (!config
|
|
992
|
+
const config = await getProxyConfig();
|
|
993
|
+
if (!config) {
|
|
1005
994
|
consola.info("No proxy configuration saved.");
|
|
1006
995
|
consola.info("");
|
|
1007
996
|
consola.info("To configure proxy, use one of:");
|
|
@@ -1010,10 +999,10 @@ const proxy = defineCommand({
|
|
|
1010
999
|
return;
|
|
1011
1000
|
}
|
|
1012
1001
|
consola.info("Current proxy configuration:");
|
|
1013
|
-
consola.info(` Status: ${config
|
|
1014
|
-
if (config
|
|
1015
|
-
if (config
|
|
1016
|
-
if (config
|
|
1002
|
+
consola.info(` Status: ${config.enabled ? "✅ Enabled" : "❌ Disabled"}`);
|
|
1003
|
+
if (config.httpProxy) consola.info(` HTTP_PROXY: ${config.httpProxy}`);
|
|
1004
|
+
if (config.httpsProxy) consola.info(` HTTPS_PROXY: ${config.httpsProxy}`);
|
|
1005
|
+
if (config.noProxy) consola.info(` NO_PROXY: ${config.noProxy}`);
|
|
1017
1006
|
return;
|
|
1018
1007
|
}
|
|
1019
1008
|
if (args.clear) {
|
|
@@ -1022,24 +1011,24 @@ const proxy = defineCommand({
|
|
|
1022
1011
|
return;
|
|
1023
1012
|
}
|
|
1024
1013
|
if (args.enable) {
|
|
1025
|
-
const config
|
|
1026
|
-
if (!config
|
|
1014
|
+
const config = await getProxyConfig();
|
|
1015
|
+
if (!config) {
|
|
1027
1016
|
consola.error("No proxy configuration saved. Use --set to configure first.");
|
|
1028
1017
|
return;
|
|
1029
1018
|
}
|
|
1030
|
-
config
|
|
1031
|
-
await saveProxyConfig(config
|
|
1019
|
+
config.enabled = true;
|
|
1020
|
+
await saveProxyConfig(config);
|
|
1032
1021
|
consola.success("Proxy enabled. It will be used on next server start.");
|
|
1033
1022
|
return;
|
|
1034
1023
|
}
|
|
1035
1024
|
if (args.disable) {
|
|
1036
|
-
const config
|
|
1037
|
-
if (!config
|
|
1025
|
+
const config = await getProxyConfig();
|
|
1026
|
+
if (!config) {
|
|
1038
1027
|
consola.info("No proxy configuration to disable.");
|
|
1039
1028
|
return;
|
|
1040
1029
|
}
|
|
1041
|
-
config
|
|
1042
|
-
await saveProxyConfig(config
|
|
1030
|
+
config.enabled = false;
|
|
1031
|
+
await saveProxyConfig(config);
|
|
1043
1032
|
consola.success("Proxy disabled. Settings are preserved.");
|
|
1044
1033
|
return;
|
|
1045
1034
|
}
|
|
@@ -1105,15 +1094,13 @@ const proxy = defineCommand({
|
|
|
1105
1094
|
}
|
|
1106
1095
|
}
|
|
1107
1096
|
});
|
|
1108
|
-
|
|
1109
1097
|
//#endregion
|
|
1110
1098
|
//#region src/lib/shell.ts
|
|
1111
1099
|
function getShell() {
|
|
1112
1100
|
const { platform, ppid, env } = process$1;
|
|
1113
1101
|
if (platform === "win32") {
|
|
1114
1102
|
try {
|
|
1115
|
-
|
|
1116
|
-
if (execSync(command, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
|
|
1103
|
+
if (execSync(`wmic process get ParentProcessId,Name | findstr "${ppid}"`, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
|
|
1117
1104
|
} catch {
|
|
1118
1105
|
return "cmd";
|
|
1119
1106
|
}
|
|
@@ -1158,7 +1145,6 @@ function generateEnvScript(envVars, commandToRun = "") {
|
|
|
1158
1145
|
if (commandBlock && commandToRun) return `${commandBlock}${shell === "cmd" ? " & " : " && "}${commandToRun}`;
|
|
1159
1146
|
return commandBlock || commandToRun;
|
|
1160
1147
|
}
|
|
1161
|
-
|
|
1162
1148
|
//#endregion
|
|
1163
1149
|
//#region src/lib/api-key-auth.ts
|
|
1164
1150
|
/**
|
|
@@ -1190,7 +1176,6 @@ const apiKeyAuthMiddleware = async (c, next) => {
|
|
|
1190
1176
|
if (!state.apiKeys.includes(providedKey)) throw new HTTPException(401, { message: "Invalid API key. Please provide a valid API key." });
|
|
1191
1177
|
await next();
|
|
1192
1178
|
};
|
|
1193
|
-
|
|
1194
1179
|
//#endregion
|
|
1195
1180
|
//#region src/lib/model-logger.ts
|
|
1196
1181
|
/**
|
|
@@ -1226,22 +1211,19 @@ async function extractModel(c) {
|
|
|
1226
1211
|
function modelLogger() {
|
|
1227
1212
|
return async (c, next) => {
|
|
1228
1213
|
const method = c.req.method;
|
|
1229
|
-
const path$
|
|
1230
|
-
const queryString = c.req.raw.url.includes("?") ? `?${c.req.raw.url.split("?")[1]}` : "";
|
|
1231
|
-
const fullPath = `${path$2}${queryString}`;
|
|
1214
|
+
const fullPath = `${c.req.path}${c.req.raw.url.includes("?") ? `?${c.req.raw.url.split("?")[1]}` : ""}`;
|
|
1232
1215
|
let model;
|
|
1233
1216
|
if (method === "POST" && c.req.header("content-type")?.includes("json")) model = await extractModel(c);
|
|
1234
1217
|
const modelPrefix = model ? `[${model}] ` : "";
|
|
1235
1218
|
const startTime = getTime();
|
|
1236
1219
|
console.log(`${modelPrefix}${startTime} <-- ${method} ${fullPath}`);
|
|
1237
|
-
const start
|
|
1220
|
+
const start = Date.now();
|
|
1238
1221
|
await next();
|
|
1239
|
-
const duration = Date.now() - start
|
|
1222
|
+
const duration = Date.now() - start;
|
|
1240
1223
|
const endTime = getTime();
|
|
1241
1224
|
console.log(`${modelPrefix}${endTime} --> ${method} ${fullPath} ${c.res.status} ${formatDuration(duration)}`);
|
|
1242
1225
|
};
|
|
1243
1226
|
}
|
|
1244
|
-
|
|
1245
1227
|
//#endregion
|
|
1246
1228
|
//#region src/services/antigravity/stream-parser.ts
|
|
1247
1229
|
/**
|
|
@@ -1274,117 +1256,115 @@ function parseSSELine(line) {
|
|
|
1274
1256
|
* Extract candidates and usage from parsed data
|
|
1275
1257
|
*/
|
|
1276
1258
|
function extractFromData(data) {
|
|
1277
|
-
const candidates = data.response?.candidates || data.candidates || [];
|
|
1278
|
-
const usage = data.response?.usageMetadata || data.usageMetadata;
|
|
1279
1259
|
return {
|
|
1280
|
-
candidates,
|
|
1281
|
-
usage
|
|
1260
|
+
candidates: data.response?.candidates || data.candidates || [],
|
|
1261
|
+
usage: data.response?.usageMetadata || data.usageMetadata
|
|
1282
1262
|
};
|
|
1283
1263
|
}
|
|
1284
1264
|
/**
|
|
1285
1265
|
* Process a single part and emit events
|
|
1286
1266
|
*/
|
|
1287
|
-
function processPart(part, state
|
|
1267
|
+
function processPart(part, state, emit) {
|
|
1288
1268
|
if (part.thought && part.text) {
|
|
1289
|
-
processThinkingPart(part.text, state
|
|
1269
|
+
processThinkingPart(part.text, state, emit);
|
|
1290
1270
|
return;
|
|
1291
1271
|
}
|
|
1292
1272
|
if (part.text && !part.thought) {
|
|
1293
|
-
processTextPart(part.text, state
|
|
1273
|
+
processTextPart(part.text, state, emit);
|
|
1294
1274
|
return;
|
|
1295
1275
|
}
|
|
1296
|
-
if (part.functionCall) processToolPart(part.functionCall, state
|
|
1276
|
+
if (part.functionCall) processToolPart(part.functionCall, state, emit);
|
|
1297
1277
|
}
|
|
1298
1278
|
/**
|
|
1299
1279
|
* Process thinking content
|
|
1300
1280
|
*/
|
|
1301
|
-
function processThinkingPart(text, state
|
|
1302
|
-
if (!state
|
|
1281
|
+
function processThinkingPart(text, state, emit) {
|
|
1282
|
+
if (!state.thinkingBlockStarted) {
|
|
1303
1283
|
emit({
|
|
1304
1284
|
type: "thinking_start",
|
|
1305
|
-
index: state
|
|
1285
|
+
index: state.contentBlockIndex
|
|
1306
1286
|
});
|
|
1307
|
-
state
|
|
1287
|
+
state.thinkingBlockStarted = true;
|
|
1308
1288
|
}
|
|
1309
1289
|
emit({
|
|
1310
1290
|
type: "thinking_delta",
|
|
1311
|
-
index: state
|
|
1291
|
+
index: state.contentBlockIndex,
|
|
1312
1292
|
text
|
|
1313
1293
|
});
|
|
1314
1294
|
}
|
|
1315
1295
|
/**
|
|
1316
1296
|
* Process text content
|
|
1317
1297
|
*/
|
|
1318
|
-
function processTextPart(text, state
|
|
1319
|
-
if (state
|
|
1298
|
+
function processTextPart(text, state, emit) {
|
|
1299
|
+
if (state.thinkingBlockStarted && !state.textBlockStarted) {
|
|
1320
1300
|
emit({
|
|
1321
1301
|
type: "thinking_stop",
|
|
1322
|
-
index: state
|
|
1302
|
+
index: state.contentBlockIndex
|
|
1323
1303
|
});
|
|
1324
|
-
state
|
|
1325
|
-
state
|
|
1304
|
+
state.contentBlockIndex++;
|
|
1305
|
+
state.thinkingBlockStarted = false;
|
|
1326
1306
|
}
|
|
1327
|
-
if (!state
|
|
1307
|
+
if (!state.textBlockStarted) {
|
|
1328
1308
|
emit({
|
|
1329
1309
|
type: "text_start",
|
|
1330
|
-
index: state
|
|
1310
|
+
index: state.contentBlockIndex
|
|
1331
1311
|
});
|
|
1332
|
-
state
|
|
1312
|
+
state.textBlockStarted = true;
|
|
1333
1313
|
}
|
|
1334
1314
|
emit({
|
|
1335
1315
|
type: "text_delta",
|
|
1336
|
-
index: state
|
|
1316
|
+
index: state.contentBlockIndex,
|
|
1337
1317
|
text
|
|
1338
1318
|
});
|
|
1339
1319
|
}
|
|
1340
1320
|
/**
|
|
1341
1321
|
* Process tool/function call
|
|
1342
1322
|
*/
|
|
1343
|
-
function processToolPart(functionCall, state
|
|
1344
|
-
if (state
|
|
1323
|
+
function processToolPart(functionCall, state, emit) {
|
|
1324
|
+
if (state.textBlockStarted) {
|
|
1345
1325
|
emit({
|
|
1346
1326
|
type: "text_stop",
|
|
1347
|
-
index: state
|
|
1327
|
+
index: state.contentBlockIndex
|
|
1348
1328
|
});
|
|
1349
|
-
state
|
|
1350
|
-
state
|
|
1351
|
-
} else if (state
|
|
1329
|
+
state.contentBlockIndex++;
|
|
1330
|
+
state.textBlockStarted = false;
|
|
1331
|
+
} else if (state.thinkingBlockStarted) {
|
|
1352
1332
|
emit({
|
|
1353
1333
|
type: "thinking_stop",
|
|
1354
|
-
index: state
|
|
1334
|
+
index: state.contentBlockIndex
|
|
1355
1335
|
});
|
|
1356
|
-
state
|
|
1357
|
-
state
|
|
1336
|
+
state.contentBlockIndex++;
|
|
1337
|
+
state.thinkingBlockStarted = false;
|
|
1358
1338
|
}
|
|
1359
1339
|
emit({
|
|
1360
1340
|
type: "tool_use",
|
|
1361
|
-
index: state
|
|
1341
|
+
index: state.contentBlockIndex,
|
|
1362
1342
|
name: functionCall.name,
|
|
1363
1343
|
args: functionCall.args
|
|
1364
1344
|
});
|
|
1365
|
-
state
|
|
1345
|
+
state.contentBlockIndex++;
|
|
1366
1346
|
}
|
|
1367
1347
|
/**
|
|
1368
1348
|
* Handle finish reason and close open blocks
|
|
1369
1349
|
*/
|
|
1370
|
-
function handleFinish(state
|
|
1371
|
-
if (state
|
|
1350
|
+
function handleFinish(state, emit) {
|
|
1351
|
+
if (state.textBlockStarted) {
|
|
1372
1352
|
emit({
|
|
1373
1353
|
type: "text_stop",
|
|
1374
|
-
index: state
|
|
1354
|
+
index: state.contentBlockIndex
|
|
1375
1355
|
});
|
|
1376
|
-
state
|
|
1377
|
-
} else if (state
|
|
1356
|
+
state.textBlockStarted = false;
|
|
1357
|
+
} else if (state.thinkingBlockStarted) {
|
|
1378
1358
|
emit({
|
|
1379
1359
|
type: "thinking_stop",
|
|
1380
|
-
index: state
|
|
1360
|
+
index: state.contentBlockIndex
|
|
1381
1361
|
});
|
|
1382
|
-
state
|
|
1362
|
+
state.thinkingBlockStarted = false;
|
|
1383
1363
|
}
|
|
1384
1364
|
emit({
|
|
1385
1365
|
type: "usage",
|
|
1386
|
-
inputTokens: state
|
|
1387
|
-
outputTokens: state
|
|
1366
|
+
inputTokens: state.inputTokens,
|
|
1367
|
+
outputTokens: state.outputTokens
|
|
1388
1368
|
});
|
|
1389
1369
|
emit({
|
|
1390
1370
|
type: "finish",
|
|
@@ -1394,15 +1374,24 @@ function handleFinish(state$1, emit) {
|
|
|
1394
1374
|
/**
|
|
1395
1375
|
* Process chunk and update buffer, returning complete lines
|
|
1396
1376
|
*/
|
|
1397
|
-
function processChunk(chunk, state
|
|
1398
|
-
state
|
|
1399
|
-
const lines = state
|
|
1400
|
-
state
|
|
1377
|
+
function processChunk(chunk, state) {
|
|
1378
|
+
state.buffer += chunk;
|
|
1379
|
+
const lines = state.buffer.split("\n");
|
|
1380
|
+
state.buffer = lines.pop() || "";
|
|
1401
1381
|
return lines;
|
|
1402
1382
|
}
|
|
1403
|
-
|
|
1404
1383
|
//#endregion
|
|
1405
1384
|
//#region src/services/antigravity/create-chat-completions.ts
|
|
1385
|
+
/**
|
|
1386
|
+
* Google Antigravity Chat Completions
|
|
1387
|
+
*
|
|
1388
|
+
* Proxy chat completion requests to Google Antigravity API or standard Gemini API.
|
|
1389
|
+
* Supports two authentication methods:
|
|
1390
|
+
* - API Key: Uses standard Gemini API (generativelanguage.googleapis.com)
|
|
1391
|
+
* - OAuth: Uses Antigravity private API (daily-cloudcode-pa.sandbox.googleapis.com)
|
|
1392
|
+
*
|
|
1393
|
+
* Based on: https://github.com/liuw1535/antigravity2api-nodejs
|
|
1394
|
+
*/
|
|
1406
1395
|
const ANTIGRAVITY_API_HOST = "daily-cloudcode-pa.sandbox.googleapis.com";
|
|
1407
1396
|
const ANTIGRAVITY_STREAM_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:streamGenerateContent?alt=sse`;
|
|
1408
1397
|
const ANTIGRAVITY_NO_STREAM_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:generateContent`;
|
|
@@ -1669,14 +1658,14 @@ function generateRequestId() {
|
|
|
1669
1658
|
function transformStreamResponse$1(response, model) {
|
|
1670
1659
|
const reader = response.body?.getReader();
|
|
1671
1660
|
if (!reader) return new Response("No response body", { status: 500 });
|
|
1672
|
-
const encoder
|
|
1661
|
+
const encoder = new TextEncoder();
|
|
1673
1662
|
const decoder = new TextDecoder();
|
|
1674
1663
|
const requestId = generateRequestId();
|
|
1675
1664
|
const stream = new ReadableStream({ async start(controller) {
|
|
1676
|
-
const state
|
|
1665
|
+
const state = createStreamState();
|
|
1677
1666
|
try {
|
|
1678
|
-
await processOpenAIStream(reader, decoder, state
|
|
1679
|
-
controller.enqueue(encoder
|
|
1667
|
+
await processOpenAIStream(reader, decoder, state, controller, encoder, requestId, model);
|
|
1668
|
+
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
1680
1669
|
controller.close();
|
|
1681
1670
|
} catch (error) {
|
|
1682
1671
|
consola.error("Stream transform error:", error);
|
|
@@ -1692,12 +1681,11 @@ function transformStreamResponse$1(response, model) {
|
|
|
1692
1681
|
/**
|
|
1693
1682
|
* Process stream and emit OpenAI format chunks
|
|
1694
1683
|
*/
|
|
1695
|
-
async function processOpenAIStream(reader, decoder, state
|
|
1684
|
+
async function processOpenAIStream(reader, decoder, state, controller, encoder, requestId, model) {
|
|
1696
1685
|
while (true) {
|
|
1697
1686
|
const { done, value } = await reader.read();
|
|
1698
1687
|
if (done) break;
|
|
1699
|
-
const
|
|
1700
|
-
const lines = processChunk(chunk, state$1);
|
|
1688
|
+
const lines = processChunk(decoder.decode(value, { stream: true }), state);
|
|
1701
1689
|
for (const line of lines) {
|
|
1702
1690
|
const data = parseSSELine(line);
|
|
1703
1691
|
if (!data) continue;
|
|
@@ -1706,7 +1694,7 @@ async function processOpenAIStream(reader, decoder, state$1, controller, encoder
|
|
|
1706
1694
|
const parts = candidate?.content?.parts ?? [];
|
|
1707
1695
|
for (const part of parts) {
|
|
1708
1696
|
const chunkData = buildOpenAIChunk(part, requestId, model, candidate?.finishReason);
|
|
1709
|
-
if (chunkData) controller.enqueue(encoder
|
|
1697
|
+
if (chunkData) controller.enqueue(encoder.encode(`data: ${JSON.stringify(chunkData)}\n\n`));
|
|
1710
1698
|
}
|
|
1711
1699
|
}
|
|
1712
1700
|
}
|
|
@@ -1761,8 +1749,7 @@ function buildOpenAIChunk(part, requestId, model, finishReason) {
|
|
|
1761
1749
|
async function transformNonStreamResponse$1(response, model) {
|
|
1762
1750
|
const rawData = await response.json();
|
|
1763
1751
|
const data = rawData.response ?? rawData;
|
|
1764
|
-
const
|
|
1765
|
-
const { content, reasoningContent, toolCalls } = extractNonStreamContent(parts);
|
|
1752
|
+
const { content, reasoningContent, toolCalls } = extractNonStreamContent((data.candidates?.[0])?.content?.parts ?? []);
|
|
1766
1753
|
const message = {
|
|
1767
1754
|
role: "assistant",
|
|
1768
1755
|
content: content || null
|
|
@@ -1812,9 +1799,13 @@ function extractNonStreamContent(parts) {
|
|
|
1812
1799
|
toolCalls
|
|
1813
1800
|
};
|
|
1814
1801
|
}
|
|
1815
|
-
|
|
1816
1802
|
//#endregion
|
|
1817
1803
|
//#region src/routes/antigravity/chat-completions/route.ts
|
|
1804
|
+
/**
|
|
1805
|
+
* Antigravity Chat Completions Route
|
|
1806
|
+
*
|
|
1807
|
+
* OpenAI-compatible chat completions endpoint for Antigravity.
|
|
1808
|
+
*/
|
|
1818
1809
|
const app$1 = new Hono();
|
|
1819
1810
|
app$1.post("/", async (c) => {
|
|
1820
1811
|
const body = await c.req.json();
|
|
@@ -1830,7 +1821,6 @@ app$1.post("/", async (c) => {
|
|
|
1830
1821
|
});
|
|
1831
1822
|
});
|
|
1832
1823
|
const antigravityChatCompletionsRoute = app$1;
|
|
1833
|
-
|
|
1834
1824
|
//#endregion
|
|
1835
1825
|
//#region src/lib/request-queue.ts
|
|
1836
1826
|
var RequestQueue = class {
|
|
@@ -1873,7 +1863,6 @@ var RequestQueue = class {
|
|
|
1873
1863
|
}
|
|
1874
1864
|
};
|
|
1875
1865
|
const antigravityQueue = new RequestQueue(2, 500);
|
|
1876
|
-
|
|
1877
1866
|
//#endregion
|
|
1878
1867
|
//#region src/services/antigravity/anthropic-events.ts
|
|
1879
1868
|
/**
|
|
@@ -2033,9 +2022,16 @@ function generateMessageId() {
|
|
|
2033
2022
|
function generateToolId() {
|
|
2034
2023
|
return `toolu_${Date.now()}`;
|
|
2035
2024
|
}
|
|
2036
|
-
|
|
2037
2025
|
//#endregion
|
|
2038
2026
|
//#region src/services/antigravity/create-messages.ts
|
|
2027
|
+
/**
|
|
2028
|
+
* Google Antigravity Messages API
|
|
2029
|
+
*
|
|
2030
|
+
* Converts Anthropic Messages API format to Antigravity format.
|
|
2031
|
+
* This enables Claude Code to use Antigravity as backend.
|
|
2032
|
+
*
|
|
2033
|
+
* Based on: https://github.com/liuw1535/antigravity2api-nodejs
|
|
2034
|
+
*/
|
|
2039
2035
|
const ANTIGRAVITY_ENDPOINTS = ["daily-cloudcode-pa.sandbox.googleapis.com", "cloudcode-pa.googleapis.com"];
|
|
2040
2036
|
let currentEndpointIndex = 0;
|
|
2041
2037
|
function getStreamUrl(host) {
|
|
@@ -2073,8 +2069,7 @@ function clearRateLimitTracker(model) {
|
|
|
2073
2069
|
if (rateLimitTracker[family]) rateLimitTracker[family].consecutiveErrors = 0;
|
|
2074
2070
|
}
|
|
2075
2071
|
function getBackoffDelay(model, baseDelay) {
|
|
2076
|
-
const
|
|
2077
|
-
const info = rateLimitTracker[family];
|
|
2072
|
+
const info = rateLimitTracker[getModelFamily(model)];
|
|
2078
2073
|
if (!info) return baseDelay;
|
|
2079
2074
|
const multiplier = Math.min(Math.pow(2, info.consecutiveErrors - 1), 60);
|
|
2080
2075
|
return Math.min(baseDelay * multiplier, 3e4);
|
|
@@ -2255,8 +2250,7 @@ function createErrorResponse(type, message, status) {
|
|
|
2255
2250
|
const MAX_RETRIES$3 = 5;
|
|
2256
2251
|
const MAX_ENDPOINT_RETRIES = 2;
|
|
2257
2252
|
async function executeAntigravityRequest(request) {
|
|
2258
|
-
const
|
|
2259
|
-
const body = buildGeminiRequest(request, projectId);
|
|
2253
|
+
const body = buildGeminiRequest(request, await getCurrentProjectId());
|
|
2260
2254
|
let endpointRetries = 0;
|
|
2261
2255
|
for (let attempt = 0; attempt <= MAX_RETRIES$3; attempt++) {
|
|
2262
2256
|
const host = getCurrentHost();
|
|
@@ -2367,7 +2361,7 @@ async function handleApiError(response, _model) {
|
|
|
2367
2361
|
/**
|
|
2368
2362
|
* Emit SSE event to controller based on stream event type
|
|
2369
2363
|
*/
|
|
2370
|
-
function emitSSEEvent(event, controller, state
|
|
2364
|
+
function emitSSEEvent(event, controller, state) {
|
|
2371
2365
|
switch (event.type) {
|
|
2372
2366
|
case "thinking_start":
|
|
2373
2367
|
controller.enqueue(createThinkingBlockStart(event.index));
|
|
@@ -2391,11 +2385,11 @@ function emitSSEEvent(event, controller, state$1) {
|
|
|
2391
2385
|
emitToolUseEvents(event, controller);
|
|
2392
2386
|
break;
|
|
2393
2387
|
case "usage":
|
|
2394
|
-
state
|
|
2395
|
-
state
|
|
2388
|
+
state.inputTokens = event.inputTokens;
|
|
2389
|
+
state.outputTokens = event.outputTokens;
|
|
2396
2390
|
break;
|
|
2397
2391
|
case "finish":
|
|
2398
|
-
controller.enqueue(createMessageDelta(event.stopReason, state
|
|
2392
|
+
controller.enqueue(createMessageDelta(event.stopReason, state.outputTokens));
|
|
2399
2393
|
break;
|
|
2400
2394
|
}
|
|
2401
2395
|
}
|
|
@@ -2417,10 +2411,10 @@ function transformStreamResponse(response, model) {
|
|
|
2417
2411
|
const decoder = new TextDecoder();
|
|
2418
2412
|
const messageId = generateMessageId();
|
|
2419
2413
|
const stream = new ReadableStream({ async start(controller) {
|
|
2420
|
-
const state
|
|
2414
|
+
const state = createStreamState();
|
|
2421
2415
|
controller.enqueue(createMessageStart(messageId, model));
|
|
2422
2416
|
try {
|
|
2423
|
-
await processStream(reader, decoder, state
|
|
2417
|
+
await processStream(reader, decoder, state, controller);
|
|
2424
2418
|
controller.enqueue(createMessageStop());
|
|
2425
2419
|
controller.close();
|
|
2426
2420
|
} catch (error) {
|
|
@@ -2437,11 +2431,11 @@ function transformStreamResponse(response, model) {
|
|
|
2437
2431
|
/**
|
|
2438
2432
|
* Process candidate parts and handle finish
|
|
2439
2433
|
*/
|
|
2440
|
-
function processCandidate(candidate, state
|
|
2434
|
+
function processCandidate(candidate, state, emit) {
|
|
2441
2435
|
const parts = candidate?.content?.parts ?? [];
|
|
2442
|
-
for (const part of parts) processPart(part, state
|
|
2436
|
+
for (const part of parts) processPart(part, state, emit);
|
|
2443
2437
|
if (candidate?.finishReason === "STOP") {
|
|
2444
|
-
handleFinish(state
|
|
2438
|
+
handleFinish(state, emit);
|
|
2445
2439
|
return true;
|
|
2446
2440
|
}
|
|
2447
2441
|
return false;
|
|
@@ -2449,23 +2443,23 @@ function processCandidate(candidate, state$1, emit) {
|
|
|
2449
2443
|
/**
|
|
2450
2444
|
* Process the stream and emit events
|
|
2451
2445
|
*/
|
|
2452
|
-
async function processStream(reader, decoder, state
|
|
2453
|
-
const emit = (event) => emitSSEEvent(event, controller, state
|
|
2446
|
+
async function processStream(reader, decoder, state, controller) {
|
|
2447
|
+
const emit = (event) => emitSSEEvent(event, controller, state);
|
|
2454
2448
|
let finished = false;
|
|
2455
2449
|
while (!finished) {
|
|
2456
2450
|
const { done, value } = await reader.read();
|
|
2457
2451
|
if (done) break;
|
|
2458
|
-
const lines = processChunk(decoder.decode(value, { stream: true }), state
|
|
2452
|
+
const lines = processChunk(decoder.decode(value, { stream: true }), state);
|
|
2459
2453
|
for (const line of lines) {
|
|
2460
2454
|
if (finished) break;
|
|
2461
2455
|
const data = parseSSELine(line);
|
|
2462
2456
|
if (!data) continue;
|
|
2463
2457
|
const { candidates, usage } = extractFromData(data);
|
|
2464
2458
|
if (usage) {
|
|
2465
|
-
state
|
|
2466
|
-
state
|
|
2459
|
+
state.inputTokens = usage.promptTokenCount ?? state.inputTokens;
|
|
2460
|
+
state.outputTokens = usage.candidatesTokenCount ?? state.outputTokens;
|
|
2467
2461
|
}
|
|
2468
|
-
if (candidates[0] && processCandidate(candidates[0], state
|
|
2462
|
+
if (candidates[0] && processCandidate(candidates[0], state, emit)) {
|
|
2469
2463
|
finished = true;
|
|
2470
2464
|
break;
|
|
2471
2465
|
}
|
|
@@ -2478,8 +2472,7 @@ async function processStream(reader, decoder, state$1, controller) {
|
|
|
2478
2472
|
async function transformNonStreamResponse(response, model) {
|
|
2479
2473
|
const rawData = await response.json();
|
|
2480
2474
|
const data = rawData.response ?? rawData;
|
|
2481
|
-
const
|
|
2482
|
-
const content = buildNonStreamContent(parts);
|
|
2475
|
+
const content = buildNonStreamContent((data.candidates?.[0])?.content?.parts ?? []);
|
|
2483
2476
|
const anthropicResponse = {
|
|
2484
2477
|
id: generateMessageId(),
|
|
2485
2478
|
type: "message",
|
|
@@ -2518,9 +2511,14 @@ function buildNonStreamContent(parts) {
|
|
|
2518
2511
|
}
|
|
2519
2512
|
return content;
|
|
2520
2513
|
}
|
|
2521
|
-
|
|
2522
2514
|
//#endregion
|
|
2523
2515
|
//#region src/routes/antigravity/messages/route.ts
|
|
2516
|
+
/**
|
|
2517
|
+
* Antigravity Messages Route
|
|
2518
|
+
*
|
|
2519
|
+
* Anthropic-compatible messages endpoint for Antigravity.
|
|
2520
|
+
* This enables Claude Code to use Antigravity as backend.
|
|
2521
|
+
*/
|
|
2524
2522
|
const antigravityMessagesRoute = new Hono();
|
|
2525
2523
|
antigravityMessagesRoute.post("/", async (c) => {
|
|
2526
2524
|
if (!state.antigravityMode) return c.json({ error: "Antigravity mode is not enabled. Start with --antigravity flag." }, 400);
|
|
@@ -2551,53 +2549,54 @@ antigravityMessagesRoute.post("/", async (c) => {
|
|
|
2551
2549
|
}, 500);
|
|
2552
2550
|
}
|
|
2553
2551
|
});
|
|
2554
|
-
|
|
2555
2552
|
//#endregion
|
|
2556
2553
|
//#region src/routes/antigravity/models/route.ts
|
|
2554
|
+
/**
|
|
2555
|
+
* Antigravity Models Route
|
|
2556
|
+
*
|
|
2557
|
+
* OpenAI-compatible models endpoint for Antigravity.
|
|
2558
|
+
*/
|
|
2557
2559
|
const app = new Hono();
|
|
2558
2560
|
app.get("/", async (c) => {
|
|
2559
2561
|
const models = await getAntigravityModels();
|
|
2560
2562
|
return c.json(models);
|
|
2561
2563
|
});
|
|
2562
2564
|
const antigravityModelsRoute = app;
|
|
2563
|
-
|
|
2564
2565
|
//#endregion
|
|
2565
2566
|
//#region src/lib/approval.ts
|
|
2566
2567
|
const awaitApproval = async () => {
|
|
2567
2568
|
if (!await consola.prompt(`Accept incoming request?`, { type: "confirm" })) throw new HTTPError("Request rejected", Response.json({ message: "Request rejected" }, { status: 403 }));
|
|
2568
2569
|
};
|
|
2569
|
-
|
|
2570
2570
|
//#endregion
|
|
2571
2571
|
//#region src/lib/rate-limit.ts
|
|
2572
|
-
async function checkRateLimit(state
|
|
2573
|
-
if (state
|
|
2572
|
+
async function checkRateLimit(state) {
|
|
2573
|
+
if (state.rateLimitSeconds === void 0) return;
|
|
2574
2574
|
const now = Date.now();
|
|
2575
|
-
if (!state
|
|
2576
|
-
state
|
|
2575
|
+
if (!state.lastRequestTimestamp) {
|
|
2576
|
+
state.lastRequestTimestamp = now;
|
|
2577
2577
|
return;
|
|
2578
2578
|
}
|
|
2579
|
-
const elapsedSeconds = (now - state
|
|
2580
|
-
if (elapsedSeconds > state
|
|
2581
|
-
state
|
|
2579
|
+
const elapsedSeconds = (now - state.lastRequestTimestamp) / 1e3;
|
|
2580
|
+
if (elapsedSeconds > state.rateLimitSeconds) {
|
|
2581
|
+
state.lastRequestTimestamp = now;
|
|
2582
2582
|
return;
|
|
2583
2583
|
}
|
|
2584
|
-
const waitTimeSeconds = Math.ceil(state
|
|
2585
|
-
if (!state
|
|
2584
|
+
const waitTimeSeconds = Math.ceil(state.rateLimitSeconds - elapsedSeconds);
|
|
2585
|
+
if (!state.rateLimitWait) {
|
|
2586
2586
|
consola.warn(`Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`);
|
|
2587
2587
|
throw new HTTPError("Rate limit exceeded", Response.json({ message: "Rate limit exceeded" }, { status: 429 }));
|
|
2588
2588
|
}
|
|
2589
2589
|
const waitTimeMs = waitTimeSeconds * 1e3;
|
|
2590
2590
|
consola.warn(`Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`);
|
|
2591
2591
|
await sleep(waitTimeMs);
|
|
2592
|
-
state
|
|
2592
|
+
state.lastRequestTimestamp = now;
|
|
2593
2593
|
consola.info("Rate limit wait completed, proceeding with request");
|
|
2594
2594
|
}
|
|
2595
|
-
|
|
2596
2595
|
//#endregion
|
|
2597
2596
|
//#region src/services/copilot/create-chat-completions.ts
|
|
2598
2597
|
const createChatCompletions = async (payload) => {
|
|
2599
2598
|
if (!state.copilotToken) throw new Error("Copilot token not found");
|
|
2600
|
-
const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x
|
|
2599
|
+
const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x) => x.type === "image_url"));
|
|
2601
2600
|
const isAgentCall = payload.messages.some((msg) => ["assistant", "tool"].includes(msg.role));
|
|
2602
2601
|
const buildHeaders = () => ({
|
|
2603
2602
|
...copilotHeaders(state, enableVision),
|
|
@@ -2658,7 +2657,6 @@ const createChatCompletions = async (payload) => {
|
|
|
2658
2657
|
if (payload.stream) return events(response);
|
|
2659
2658
|
return await response.json();
|
|
2660
2659
|
};
|
|
2661
|
-
|
|
2662
2660
|
//#endregion
|
|
2663
2661
|
//#region src/routes/chat-completions/handler.ts
|
|
2664
2662
|
/**
|
|
@@ -2698,7 +2696,6 @@ async function handleCompletion$1(c) {
|
|
|
2698
2696
|
});
|
|
2699
2697
|
}
|
|
2700
2698
|
const isNonStreaming$1 = (response) => Object.hasOwn(response, "choices");
|
|
2701
|
-
|
|
2702
2699
|
//#endregion
|
|
2703
2700
|
//#region src/routes/chat-completions/route.ts
|
|
2704
2701
|
const completionRoutes = new Hono();
|
|
@@ -2709,7 +2706,6 @@ completionRoutes.post("/", async (c) => {
|
|
|
2709
2706
|
return await forwardError(c, error);
|
|
2710
2707
|
}
|
|
2711
2708
|
});
|
|
2712
|
-
|
|
2713
2709
|
//#endregion
|
|
2714
2710
|
//#region src/services/copilot/create-embeddings.ts
|
|
2715
2711
|
const createEmbeddings = async (payload) => {
|
|
@@ -2722,20 +2718,17 @@ const createEmbeddings = async (payload) => {
|
|
|
2722
2718
|
if (!response.ok) throw new HTTPError("Failed to create embeddings", response);
|
|
2723
2719
|
return await response.json();
|
|
2724
2720
|
};
|
|
2725
|
-
|
|
2726
2721
|
//#endregion
|
|
2727
2722
|
//#region src/routes/embeddings/route.ts
|
|
2728
2723
|
const embeddingRoutes = new Hono();
|
|
2729
2724
|
embeddingRoutes.post("/", async (c) => {
|
|
2730
2725
|
try {
|
|
2731
|
-
const
|
|
2732
|
-
const response = await createEmbeddings(paylod);
|
|
2726
|
+
const response = await createEmbeddings(await c.req.json());
|
|
2733
2727
|
return c.json(response);
|
|
2734
2728
|
} catch (error) {
|
|
2735
2729
|
return await forwardError(c, error);
|
|
2736
2730
|
}
|
|
2737
2731
|
});
|
|
2738
|
-
|
|
2739
2732
|
//#endregion
|
|
2740
2733
|
//#region src/lib/tokenizer.ts
|
|
2741
2734
|
const ENCODING_MAP = {
|
|
@@ -2749,11 +2742,11 @@ const encodingCache = /* @__PURE__ */ new Map();
|
|
|
2749
2742
|
/**
|
|
2750
2743
|
* Calculate tokens for tool calls
|
|
2751
2744
|
*/
|
|
2752
|
-
const calculateToolCallsTokens = (toolCalls, encoder
|
|
2745
|
+
const calculateToolCallsTokens = (toolCalls, encoder, constants) => {
|
|
2753
2746
|
let tokens = 0;
|
|
2754
2747
|
for (const toolCall of toolCalls) {
|
|
2755
2748
|
tokens += constants.funcInit;
|
|
2756
|
-
tokens += encoder
|
|
2749
|
+
tokens += encoder.encode(JSON.stringify(toolCall)).length;
|
|
2757
2750
|
}
|
|
2758
2751
|
tokens += constants.funcEnd;
|
|
2759
2752
|
return tokens;
|
|
@@ -2761,34 +2754,34 @@ const calculateToolCallsTokens = (toolCalls, encoder$1, constants) => {
|
|
|
2761
2754
|
/**
|
|
2762
2755
|
* Calculate tokens for content parts
|
|
2763
2756
|
*/
|
|
2764
|
-
const calculateContentPartsTokens = (contentParts, encoder
|
|
2757
|
+
const calculateContentPartsTokens = (contentParts, encoder) => {
|
|
2765
2758
|
let tokens = 0;
|
|
2766
|
-
for (const part of contentParts) if (part.type === "image_url") tokens += encoder
|
|
2767
|
-
else if (part.text) tokens += encoder
|
|
2759
|
+
for (const part of contentParts) if (part.type === "image_url") tokens += encoder.encode(part.image_url.url).length + 85;
|
|
2760
|
+
else if (part.text) tokens += encoder.encode(part.text).length;
|
|
2768
2761
|
return tokens;
|
|
2769
2762
|
};
|
|
2770
2763
|
/**
|
|
2771
2764
|
* Calculate tokens for a single message
|
|
2772
2765
|
*/
|
|
2773
|
-
const calculateMessageTokens = (message, encoder
|
|
2766
|
+
const calculateMessageTokens = (message, encoder, constants) => {
|
|
2774
2767
|
const tokensPerMessage = 3;
|
|
2775
2768
|
const tokensPerName = 1;
|
|
2776
2769
|
let tokens = tokensPerMessage;
|
|
2777
2770
|
for (const [key, value] of Object.entries(message)) {
|
|
2778
|
-
if (typeof value === "string") tokens += encoder
|
|
2771
|
+
if (typeof value === "string") tokens += encoder.encode(value).length;
|
|
2779
2772
|
if (key === "name") tokens += tokensPerName;
|
|
2780
|
-
if (key === "tool_calls") tokens += calculateToolCallsTokens(value, encoder
|
|
2781
|
-
if (key === "content" && Array.isArray(value)) tokens += calculateContentPartsTokens(value, encoder
|
|
2773
|
+
if (key === "tool_calls") tokens += calculateToolCallsTokens(value, encoder, constants);
|
|
2774
|
+
if (key === "content" && Array.isArray(value)) tokens += calculateContentPartsTokens(value, encoder);
|
|
2782
2775
|
}
|
|
2783
2776
|
return tokens;
|
|
2784
2777
|
};
|
|
2785
2778
|
/**
|
|
2786
2779
|
* Calculate tokens using custom algorithm
|
|
2787
2780
|
*/
|
|
2788
|
-
const calculateTokens = (messages, encoder
|
|
2781
|
+
const calculateTokens = (messages, encoder, constants) => {
|
|
2789
2782
|
if (messages.length === 0) return 0;
|
|
2790
2783
|
let numTokens = 0;
|
|
2791
|
-
for (const message of messages) numTokens += calculateMessageTokens(message, encoder
|
|
2784
|
+
for (const message of messages) numTokens += calculateMessageTokens(message, encoder, constants);
|
|
2792
2785
|
numTokens += 3;
|
|
2793
2786
|
return numTokens;
|
|
2794
2787
|
};
|
|
@@ -2840,7 +2833,7 @@ const getModelConstants = (model) => {
|
|
|
2840
2833
|
* Calculate tokens for a single parameter
|
|
2841
2834
|
*/
|
|
2842
2835
|
const calculateParameterTokens = (key, prop, context) => {
|
|
2843
|
-
const { encoder
|
|
2836
|
+
const { encoder, constants } = context;
|
|
2844
2837
|
let tokens = constants.propKey;
|
|
2845
2838
|
if (typeof prop !== "object" || prop === null) return tokens;
|
|
2846
2839
|
const param = prop;
|
|
@@ -2851,12 +2844,12 @@ const calculateParameterTokens = (key, prop, context) => {
|
|
|
2851
2844
|
tokens += constants.enumInit;
|
|
2852
2845
|
for (const item of param.enum) {
|
|
2853
2846
|
tokens += constants.enumItem;
|
|
2854
|
-
tokens += encoder
|
|
2847
|
+
tokens += encoder.encode(String(item)).length;
|
|
2855
2848
|
}
|
|
2856
2849
|
}
|
|
2857
2850
|
if (paramDesc.endsWith(".")) paramDesc = paramDesc.slice(0, -1);
|
|
2858
2851
|
const line = `${paramName}:${paramType}:${paramDesc}`;
|
|
2859
|
-
tokens += encoder
|
|
2852
|
+
tokens += encoder.encode(line).length;
|
|
2860
2853
|
const excludedKeys = new Set([
|
|
2861
2854
|
"type",
|
|
2862
2855
|
"description",
|
|
@@ -2865,14 +2858,14 @@ const calculateParameterTokens = (key, prop, context) => {
|
|
|
2865
2858
|
for (const propertyName of Object.keys(param)) if (!excludedKeys.has(propertyName)) {
|
|
2866
2859
|
const propertyValue = param[propertyName];
|
|
2867
2860
|
const propertyText = typeof propertyValue === "string" ? propertyValue : JSON.stringify(propertyValue);
|
|
2868
|
-
tokens += encoder
|
|
2861
|
+
tokens += encoder.encode(`${propertyName}:${propertyText}`).length;
|
|
2869
2862
|
}
|
|
2870
2863
|
return tokens;
|
|
2871
2864
|
};
|
|
2872
2865
|
/**
|
|
2873
2866
|
* Calculate tokens for function parameters
|
|
2874
2867
|
*/
|
|
2875
|
-
const calculateParametersTokens = (parameters, encoder
|
|
2868
|
+
const calculateParametersTokens = (parameters, encoder, constants) => {
|
|
2876
2869
|
if (!parameters || typeof parameters !== "object") return 0;
|
|
2877
2870
|
const params = parameters;
|
|
2878
2871
|
let tokens = 0;
|
|
@@ -2881,36 +2874,36 @@ const calculateParametersTokens = (parameters, encoder$1, constants) => {
|
|
|
2881
2874
|
if (Object.keys(properties).length > 0) {
|
|
2882
2875
|
tokens += constants.propInit;
|
|
2883
2876
|
for (const propKey of Object.keys(properties)) tokens += calculateParameterTokens(propKey, properties[propKey], {
|
|
2884
|
-
encoder
|
|
2877
|
+
encoder,
|
|
2885
2878
|
constants
|
|
2886
2879
|
});
|
|
2887
2880
|
}
|
|
2888
2881
|
} else {
|
|
2889
2882
|
const paramText = typeof value === "string" ? value : JSON.stringify(value);
|
|
2890
|
-
tokens += encoder
|
|
2883
|
+
tokens += encoder.encode(`${key}:${paramText}`).length;
|
|
2891
2884
|
}
|
|
2892
2885
|
return tokens;
|
|
2893
2886
|
};
|
|
2894
2887
|
/**
|
|
2895
2888
|
* Calculate tokens for a single tool
|
|
2896
2889
|
*/
|
|
2897
|
-
const calculateToolTokens = (tool, encoder
|
|
2890
|
+
const calculateToolTokens = (tool, encoder, constants) => {
|
|
2898
2891
|
let tokens = constants.funcInit;
|
|
2899
2892
|
const func = tool.function;
|
|
2900
2893
|
const fName = func.name;
|
|
2901
2894
|
let fDesc = func.description || "";
|
|
2902
2895
|
if (fDesc.endsWith(".")) fDesc = fDesc.slice(0, -1);
|
|
2903
2896
|
const line = fName + ":" + fDesc;
|
|
2904
|
-
tokens += encoder
|
|
2905
|
-
if (typeof func.parameters === "object" && func.parameters !== null) tokens += calculateParametersTokens(func.parameters, encoder
|
|
2897
|
+
tokens += encoder.encode(line).length;
|
|
2898
|
+
if (typeof func.parameters === "object" && func.parameters !== null) tokens += calculateParametersTokens(func.parameters, encoder, constants);
|
|
2906
2899
|
return tokens;
|
|
2907
2900
|
};
|
|
2908
2901
|
/**
|
|
2909
2902
|
* Calculate token count for tools based on model
|
|
2910
2903
|
*/
|
|
2911
|
-
const numTokensForTools = (tools, encoder
|
|
2904
|
+
const numTokensForTools = (tools, encoder, constants) => {
|
|
2912
2905
|
let funcTokenCount = 0;
|
|
2913
|
-
for (const tool of tools) funcTokenCount += calculateToolTokens(tool, encoder
|
|
2906
|
+
for (const tool of tools) funcTokenCount += calculateToolTokens(tool, encoder, constants);
|
|
2914
2907
|
funcTokenCount += constants.funcEnd;
|
|
2915
2908
|
return funcTokenCount;
|
|
2916
2909
|
};
|
|
@@ -2918,17 +2911,15 @@ const numTokensForTools = (tools, encoder$1, constants) => {
|
|
|
2918
2911
|
* Calculate the token count of messages, supporting multiple GPT encoders
|
|
2919
2912
|
*/
|
|
2920
2913
|
const getTokenCount = async (payload, model) => {
|
|
2921
|
-
const
|
|
2922
|
-
const encoder$1 = await getEncodeChatFunction(tokenizer);
|
|
2914
|
+
const encoder = await getEncodeChatFunction(getTokenizerFromModel(model));
|
|
2923
2915
|
const constants = getModelConstants(model);
|
|
2924
|
-
let inputTokens = calculateTokens(payload.messages, encoder
|
|
2925
|
-
if (payload.tools && payload.tools.length > 0) inputTokens += numTokensForTools(payload.tools, encoder
|
|
2916
|
+
let inputTokens = calculateTokens(payload.messages, encoder, constants);
|
|
2917
|
+
if (payload.tools && payload.tools.length > 0) inputTokens += numTokensForTools(payload.tools, encoder, constants);
|
|
2926
2918
|
return {
|
|
2927
2919
|
input: inputTokens,
|
|
2928
2920
|
output: 0
|
|
2929
2921
|
};
|
|
2930
2922
|
};
|
|
2931
|
-
|
|
2932
2923
|
//#endregion
|
|
2933
2924
|
//#region src/routes/messages/utils.ts
|
|
2934
2925
|
function mapOpenAIStopReasonToAnthropic(finishReason) {
|
|
@@ -2940,7 +2931,6 @@ function mapOpenAIStopReasonToAnthropic(finishReason) {
|
|
|
2940
2931
|
content_filter: "end_turn"
|
|
2941
2932
|
}[finishReason];
|
|
2942
2933
|
}
|
|
2943
|
-
|
|
2944
2934
|
//#endregion
|
|
2945
2935
|
//#region src/routes/messages/non-stream-translation.ts
|
|
2946
2936
|
function translateToOpenAI(payload) {
|
|
@@ -3137,7 +3127,6 @@ function getAnthropicToolUseBlocks(toolCalls) {
|
|
|
3137
3127
|
input: JSON.parse(toolCall.function.arguments)
|
|
3138
3128
|
}));
|
|
3139
3129
|
}
|
|
3140
|
-
|
|
3141
3130
|
//#endregion
|
|
3142
3131
|
//#region src/routes/messages/count-tokens-handler.ts
|
|
3143
3132
|
/**
|
|
@@ -3177,20 +3166,19 @@ async function handleCountTokens(c) {
|
|
|
3177
3166
|
return c.json({ input_tokens: 1 });
|
|
3178
3167
|
}
|
|
3179
3168
|
}
|
|
3180
|
-
|
|
3181
3169
|
//#endregion
|
|
3182
3170
|
//#region src/routes/messages/stream-translation.ts
|
|
3183
|
-
function isToolBlockOpen(state
|
|
3184
|
-
if (!state
|
|
3185
|
-
return Object.values(state
|
|
3171
|
+
function isToolBlockOpen(state) {
|
|
3172
|
+
if (!state.contentBlockOpen) return false;
|
|
3173
|
+
return Object.values(state.toolCalls).some((tc) => tc.anthropicBlockIndex === state.contentBlockIndex);
|
|
3186
3174
|
}
|
|
3187
|
-
function translateChunkToAnthropicEvents(chunk, state
|
|
3188
|
-
const events
|
|
3189
|
-
if (chunk.choices.length === 0) return events
|
|
3175
|
+
function translateChunkToAnthropicEvents(chunk, state) {
|
|
3176
|
+
const events = [];
|
|
3177
|
+
if (chunk.choices.length === 0) return events;
|
|
3190
3178
|
const choice = chunk.choices[0];
|
|
3191
3179
|
const { delta } = choice;
|
|
3192
|
-
if (!state
|
|
3193
|
-
events
|
|
3180
|
+
if (!state.messageStartSent) {
|
|
3181
|
+
events.push({
|
|
3194
3182
|
type: "message_start",
|
|
3195
3183
|
message: {
|
|
3196
3184
|
id: chunk.id,
|
|
@@ -3207,31 +3195,31 @@ function translateChunkToAnthropicEvents(chunk, state$1) {
|
|
|
3207
3195
|
}
|
|
3208
3196
|
}
|
|
3209
3197
|
});
|
|
3210
|
-
state
|
|
3198
|
+
state.messageStartSent = true;
|
|
3211
3199
|
}
|
|
3212
3200
|
if (delta.content) {
|
|
3213
|
-
if (isToolBlockOpen(state
|
|
3214
|
-
events
|
|
3201
|
+
if (isToolBlockOpen(state)) {
|
|
3202
|
+
events.push({
|
|
3215
3203
|
type: "content_block_stop",
|
|
3216
|
-
index: state
|
|
3204
|
+
index: state.contentBlockIndex
|
|
3217
3205
|
});
|
|
3218
|
-
state
|
|
3219
|
-
state
|
|
3206
|
+
state.contentBlockIndex++;
|
|
3207
|
+
state.contentBlockOpen = false;
|
|
3220
3208
|
}
|
|
3221
|
-
if (!state
|
|
3222
|
-
events
|
|
3209
|
+
if (!state.contentBlockOpen) {
|
|
3210
|
+
events.push({
|
|
3223
3211
|
type: "content_block_start",
|
|
3224
|
-
index: state
|
|
3212
|
+
index: state.contentBlockIndex,
|
|
3225
3213
|
content_block: {
|
|
3226
3214
|
type: "text",
|
|
3227
3215
|
text: ""
|
|
3228
3216
|
}
|
|
3229
3217
|
});
|
|
3230
|
-
state
|
|
3218
|
+
state.contentBlockOpen = true;
|
|
3231
3219
|
}
|
|
3232
|
-
events
|
|
3220
|
+
events.push({
|
|
3233
3221
|
type: "content_block_delta",
|
|
3234
|
-
index: state
|
|
3222
|
+
index: state.contentBlockIndex,
|
|
3235
3223
|
delta: {
|
|
3236
3224
|
type: "text_delta",
|
|
3237
3225
|
text: delta.content
|
|
@@ -3240,21 +3228,21 @@ function translateChunkToAnthropicEvents(chunk, state$1) {
|
|
|
3240
3228
|
}
|
|
3241
3229
|
if (delta.tool_calls) for (const toolCall of delta.tool_calls) {
|
|
3242
3230
|
if (toolCall.id && toolCall.function?.name) {
|
|
3243
|
-
if (state
|
|
3244
|
-
events
|
|
3231
|
+
if (state.contentBlockOpen) {
|
|
3232
|
+
events.push({
|
|
3245
3233
|
type: "content_block_stop",
|
|
3246
|
-
index: state
|
|
3234
|
+
index: state.contentBlockIndex
|
|
3247
3235
|
});
|
|
3248
|
-
state
|
|
3249
|
-
state
|
|
3236
|
+
state.contentBlockIndex++;
|
|
3237
|
+
state.contentBlockOpen = false;
|
|
3250
3238
|
}
|
|
3251
|
-
const anthropicBlockIndex = state
|
|
3252
|
-
state
|
|
3239
|
+
const anthropicBlockIndex = state.contentBlockIndex;
|
|
3240
|
+
state.toolCalls[toolCall.index] = {
|
|
3253
3241
|
id: toolCall.id,
|
|
3254
3242
|
name: toolCall.function.name,
|
|
3255
3243
|
anthropicBlockIndex
|
|
3256
3244
|
};
|
|
3257
|
-
events
|
|
3245
|
+
events.push({
|
|
3258
3246
|
type: "content_block_start",
|
|
3259
3247
|
index: anthropicBlockIndex,
|
|
3260
3248
|
content_block: {
|
|
@@ -3264,11 +3252,11 @@ function translateChunkToAnthropicEvents(chunk, state$1) {
|
|
|
3264
3252
|
input: {}
|
|
3265
3253
|
}
|
|
3266
3254
|
});
|
|
3267
|
-
state
|
|
3255
|
+
state.contentBlockOpen = true;
|
|
3268
3256
|
}
|
|
3269
3257
|
if (toolCall.function?.arguments) {
|
|
3270
|
-
const toolCallInfo = state
|
|
3271
|
-
if (toolCallInfo) events
|
|
3258
|
+
const toolCallInfo = state.toolCalls[toolCall.index];
|
|
3259
|
+
if (toolCallInfo) events.push({
|
|
3272
3260
|
type: "content_block_delta",
|
|
3273
3261
|
index: toolCallInfo.anthropicBlockIndex,
|
|
3274
3262
|
delta: {
|
|
@@ -3279,14 +3267,14 @@ function translateChunkToAnthropicEvents(chunk, state$1) {
|
|
|
3279
3267
|
}
|
|
3280
3268
|
}
|
|
3281
3269
|
if (choice.finish_reason) {
|
|
3282
|
-
if (state
|
|
3283
|
-
events
|
|
3270
|
+
if (state.contentBlockOpen) {
|
|
3271
|
+
events.push({
|
|
3284
3272
|
type: "content_block_stop",
|
|
3285
|
-
index: state
|
|
3273
|
+
index: state.contentBlockIndex
|
|
3286
3274
|
});
|
|
3287
|
-
state
|
|
3275
|
+
state.contentBlockOpen = false;
|
|
3288
3276
|
}
|
|
3289
|
-
events
|
|
3277
|
+
events.push({
|
|
3290
3278
|
type: "message_delta",
|
|
3291
3279
|
delta: {
|
|
3292
3280
|
stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),
|
|
@@ -3299,15 +3287,13 @@ function translateChunkToAnthropicEvents(chunk, state$1) {
|
|
|
3299
3287
|
}
|
|
3300
3288
|
}, { type: "message_stop" });
|
|
3301
3289
|
}
|
|
3302
|
-
return events
|
|
3290
|
+
return events;
|
|
3303
3291
|
}
|
|
3304
|
-
|
|
3305
3292
|
//#endregion
|
|
3306
3293
|
//#region src/routes/messages/handler.ts
|
|
3307
3294
|
async function handleCompletion(c) {
|
|
3308
3295
|
await checkRateLimit(state);
|
|
3309
|
-
const
|
|
3310
|
-
const openAIPayload = translateToOpenAI(anthropicPayload);
|
|
3296
|
+
const openAIPayload = translateToOpenAI(await c.req.json());
|
|
3311
3297
|
if (state.manualApprove) await awaitApproval();
|
|
3312
3298
|
const response = await createChatCompletions(openAIPayload);
|
|
3313
3299
|
if (isNonStreaming(response)) {
|
|
@@ -3324,9 +3310,8 @@ async function handleCompletion(c) {
|
|
|
3324
3310
|
for await (const rawEvent of response) {
|
|
3325
3311
|
if (rawEvent.data === "[DONE]") break;
|
|
3326
3312
|
if (!rawEvent.data) continue;
|
|
3327
|
-
const
|
|
3328
|
-
const events
|
|
3329
|
-
for (const event of events$1) await stream.writeSSE({
|
|
3313
|
+
const events = translateChunkToAnthropicEvents(JSON.parse(rawEvent.data), streamState);
|
|
3314
|
+
for (const event of events) await stream.writeSSE({
|
|
3330
3315
|
event: event.type,
|
|
3331
3316
|
data: JSON.stringify(event)
|
|
3332
3317
|
});
|
|
@@ -3334,7 +3319,6 @@ async function handleCompletion(c) {
|
|
|
3334
3319
|
});
|
|
3335
3320
|
}
|
|
3336
3321
|
const isNonStreaming = (response) => Object.hasOwn(response, "choices");
|
|
3337
|
-
|
|
3338
3322
|
//#endregion
|
|
3339
3323
|
//#region src/routes/messages/route.ts
|
|
3340
3324
|
const messageRoutes = new Hono();
|
|
@@ -3352,7 +3336,6 @@ messageRoutes.post("/count_tokens", async (c) => {
|
|
|
3352
3336
|
return await forwardError(c, error);
|
|
3353
3337
|
}
|
|
3354
3338
|
});
|
|
3355
|
-
|
|
3356
3339
|
//#endregion
|
|
3357
3340
|
//#region src/routes/models/route.ts
|
|
3358
3341
|
const modelRoutes = new Hono();
|
|
@@ -3377,7 +3360,6 @@ modelRoutes.get("/", async (c) => {
|
|
|
3377
3360
|
return await forwardError(c, error);
|
|
3378
3361
|
}
|
|
3379
3362
|
});
|
|
3380
|
-
|
|
3381
3363
|
//#endregion
|
|
3382
3364
|
//#region src/routes/token/route.ts
|
|
3383
3365
|
const tokenRoute = new Hono();
|
|
@@ -3392,15 +3374,14 @@ tokenRoute.get("/", (c) => {
|
|
|
3392
3374
|
}, 500);
|
|
3393
3375
|
}
|
|
3394
3376
|
});
|
|
3395
|
-
|
|
3396
3377
|
//#endregion
|
|
3397
3378
|
//#region src/routes/usage/route.ts
|
|
3398
3379
|
const usageRoute = new Hono();
|
|
3399
3380
|
usageRoute.get("/", async (c) => {
|
|
3400
3381
|
try {
|
|
3401
3382
|
if (state.antigravityMode) {
|
|
3402
|
-
const usage
|
|
3403
|
-
return c.json(usage
|
|
3383
|
+
const usage = await getAntigravityUsage();
|
|
3384
|
+
return c.json(usage);
|
|
3404
3385
|
}
|
|
3405
3386
|
if (state.zenMode) return c.json({
|
|
3406
3387
|
error: "Usage statistics not available for Zen mode",
|
|
@@ -3416,9 +3397,13 @@ usageRoute.get("/", async (c) => {
|
|
|
3416
3397
|
return c.json({ error: "Failed to fetch Copilot usage" }, 500);
|
|
3417
3398
|
}
|
|
3418
3399
|
});
|
|
3419
|
-
|
|
3420
3400
|
//#endregion
|
|
3421
3401
|
//#region src/services/zen/create-chat-completions.ts
|
|
3402
|
+
/**
|
|
3403
|
+
* OpenCode Zen Chat Completions Proxy
|
|
3404
|
+
*
|
|
3405
|
+
* Proxies chat completion requests to OpenCode Zen API.
|
|
3406
|
+
*/
|
|
3422
3407
|
const MAX_RETRIES$2 = 5;
|
|
3423
3408
|
const DEFAULT_RETRY_DELAY$2 = 500;
|
|
3424
3409
|
/**
|
|
@@ -3474,9 +3459,13 @@ async function createZenChatCompletions(request, signal) {
|
|
|
3474
3459
|
}
|
|
3475
3460
|
throw new Error("Max retries exceeded");
|
|
3476
3461
|
}
|
|
3477
|
-
|
|
3478
3462
|
//#endregion
|
|
3479
3463
|
//#region src/routes/zen/chat-completions/route.ts
|
|
3464
|
+
/**
|
|
3465
|
+
* OpenCode Zen Chat Completions Route
|
|
3466
|
+
*
|
|
3467
|
+
* Proxies OpenAI-format chat completion requests to Zen.
|
|
3468
|
+
*/
|
|
3480
3469
|
const zenCompletionRoutes = new Hono();
|
|
3481
3470
|
zenCompletionRoutes.post("/", async (c) => {
|
|
3482
3471
|
if (!state.zenMode || !state.zenApiKey) return c.json({ error: "Zen mode is not enabled. Start with --zen flag." }, 400);
|
|
@@ -3504,9 +3493,13 @@ zenCompletionRoutes.post("/", async (c) => {
|
|
|
3504
3493
|
} }, 500);
|
|
3505
3494
|
}
|
|
3506
3495
|
});
|
|
3507
|
-
|
|
3508
3496
|
//#endregion
|
|
3509
3497
|
//#region src/services/zen/create-messages.ts
|
|
3498
|
+
/**
|
|
3499
|
+
* OpenCode Zen Messages Proxy
|
|
3500
|
+
*
|
|
3501
|
+
* Proxies Anthropic-format message requests to OpenCode Zen API.
|
|
3502
|
+
*/
|
|
3510
3503
|
const MAX_RETRIES$1 = 5;
|
|
3511
3504
|
const DEFAULT_RETRY_DELAY$1 = 500;
|
|
3512
3505
|
/**
|
|
@@ -3563,9 +3556,14 @@ async function createZenMessages(request, signal) {
|
|
|
3563
3556
|
}
|
|
3564
3557
|
throw new Error("Max retries exceeded");
|
|
3565
3558
|
}
|
|
3566
|
-
|
|
3567
3559
|
//#endregion
|
|
3568
3560
|
//#region src/routes/zen/messages/route.ts
|
|
3561
|
+
/**
|
|
3562
|
+
* OpenCode Zen Messages Route
|
|
3563
|
+
*
|
|
3564
|
+
* Proxies Anthropic-format message requests to Zen.
|
|
3565
|
+
* This enables Claude Code to use Zen as backend.
|
|
3566
|
+
*/
|
|
3569
3567
|
const zenMessageRoutes = new Hono();
|
|
3570
3568
|
zenMessageRoutes.post("/", async (c) => {
|
|
3571
3569
|
if (!state.zenMode || !state.zenApiKey) return c.json({ error: "Zen mode is not enabled. Start with --zen flag." }, 400);
|
|
@@ -3596,15 +3594,19 @@ zenMessageRoutes.post("/", async (c) => {
|
|
|
3596
3594
|
}, 500);
|
|
3597
3595
|
}
|
|
3598
3596
|
});
|
|
3599
|
-
|
|
3600
3597
|
//#endregion
|
|
3601
3598
|
//#region src/routes/zen/models/route.ts
|
|
3599
|
+
/**
|
|
3600
|
+
* OpenCode Zen Models Route
|
|
3601
|
+
*
|
|
3602
|
+
* Returns available models from Zen.
|
|
3603
|
+
*/
|
|
3602
3604
|
const zenModelRoutes = new Hono();
|
|
3603
3605
|
zenModelRoutes.get("/", async (c) => {
|
|
3604
3606
|
if (!state.zenMode || !state.zenApiKey) return c.json({ error: "Zen mode is not enabled. Start with --zen flag." }, 400);
|
|
3605
3607
|
try {
|
|
3606
3608
|
if (state.zenModels) return c.json(state.zenModels);
|
|
3607
|
-
const { getZenModels } = await import("./get-models-
|
|
3609
|
+
const { getZenModels } = await import("./get-models-onnSXkNI.js");
|
|
3608
3610
|
const models = await getZenModels();
|
|
3609
3611
|
state.zenModels = models;
|
|
3610
3612
|
return c.json(models);
|
|
@@ -3616,9 +3618,14 @@ zenModelRoutes.get("/", async (c) => {
|
|
|
3616
3618
|
} }, 500);
|
|
3617
3619
|
}
|
|
3618
3620
|
});
|
|
3619
|
-
|
|
3620
3621
|
//#endregion
|
|
3621
3622
|
//#region src/services/zen/create-responses.ts
|
|
3623
|
+
/**
|
|
3624
|
+
* OpenCode Zen Responses Proxy
|
|
3625
|
+
*
|
|
3626
|
+
* Proxies OpenAI Responses API requests to OpenCode Zen.
|
|
3627
|
+
* Used for GPT-5 series models with stateful, agentic tool-use.
|
|
3628
|
+
*/
|
|
3622
3629
|
const MAX_RETRIES = 5;
|
|
3623
3630
|
const DEFAULT_RETRY_DELAY = 500;
|
|
3624
3631
|
/**
|
|
@@ -3674,9 +3681,14 @@ async function createZenResponses(request, signal) {
|
|
|
3674
3681
|
}
|
|
3675
3682
|
throw new Error("Max retries exceeded");
|
|
3676
3683
|
}
|
|
3677
|
-
|
|
3678
3684
|
//#endregion
|
|
3679
3685
|
//#region src/routes/zen/responses/route.ts
|
|
3686
|
+
/**
|
|
3687
|
+
* OpenCode Zen Responses Route
|
|
3688
|
+
*
|
|
3689
|
+
* Proxies OpenAI Responses API requests to Zen.
|
|
3690
|
+
* Used for GPT-5 series models.
|
|
3691
|
+
*/
|
|
3680
3692
|
const zenResponsesRoutes = new Hono();
|
|
3681
3693
|
zenResponsesRoutes.post("/", async (c) => {
|
|
3682
3694
|
if (!state.zenMode || !state.zenApiKey) return c.json({ error: "Zen mode is not enabled. Start with --zen flag." }, 400);
|
|
@@ -3704,7 +3716,6 @@ zenResponsesRoutes.post("/", async (c) => {
|
|
|
3704
3716
|
} }, 500);
|
|
3705
3717
|
}
|
|
3706
3718
|
});
|
|
3707
|
-
|
|
3708
3719
|
//#endregion
|
|
3709
3720
|
//#region src/server.ts
|
|
3710
3721
|
const server = new Hono();
|
|
@@ -3798,7 +3809,6 @@ server.route("/zen/v1/responses", zenResponsesRoutes);
|
|
|
3798
3809
|
server.route("/antigravity/v1/chat/completions", antigravityChatCompletionsRoute);
|
|
3799
3810
|
server.route("/antigravity/v1/models", antigravityModelsRoute);
|
|
3800
3811
|
server.route("/antigravity/v1/messages", antigravityMessagesRoute);
|
|
3801
|
-
|
|
3802
3812
|
//#endregion
|
|
3803
3813
|
//#region src/start.ts
|
|
3804
3814
|
/**
|
|
@@ -3827,51 +3837,51 @@ server.route("/antigravity/v1/messages", antigravityMessagesRoute);
|
|
|
3827
3837
|
* - antigravityClientId: Google OAuth Client ID (optional; overrides env/default)
|
|
3828
3838
|
* - antigravityClientSecret: Google OAuth Client Secret (optional; overrides env/default)
|
|
3829
3839
|
*/
|
|
3830
|
-
async function runServer(options
|
|
3840
|
+
async function runServer(options) {
|
|
3831
3841
|
const savedProxyApplied = await applyProxyConfig();
|
|
3832
|
-
if (options
|
|
3842
|
+
if (options.proxyEnv) initProxyFromEnv();
|
|
3833
3843
|
else if (savedProxyApplied) initProxyFromEnv();
|
|
3834
|
-
if (options
|
|
3844
|
+
if (options.verbose) {
|
|
3835
3845
|
consola.level = 5;
|
|
3836
3846
|
consola.info("Verbose logging enabled");
|
|
3837
3847
|
}
|
|
3838
|
-
state.accountType = options
|
|
3839
|
-
if (options
|
|
3840
|
-
state.manualApprove = options
|
|
3841
|
-
state.rateLimitSeconds = options
|
|
3842
|
-
state.rateLimitWait = options
|
|
3843
|
-
state.showToken = options
|
|
3844
|
-
state.apiKeys = options
|
|
3848
|
+
state.accountType = options.accountType;
|
|
3849
|
+
if (options.accountType !== "individual") consola.info(`Using ${options.accountType} plan GitHub account`);
|
|
3850
|
+
state.manualApprove = options.manual;
|
|
3851
|
+
state.rateLimitSeconds = options.rateLimit;
|
|
3852
|
+
state.rateLimitWait = options.rateLimitWait;
|
|
3853
|
+
state.showToken = options.showToken;
|
|
3854
|
+
state.apiKeys = options.apiKeys;
|
|
3845
3855
|
if (state.apiKeys && state.apiKeys.length > 0) consola.info(`API key authentication enabled with ${state.apiKeys.length} key(s)`);
|
|
3846
3856
|
await ensurePaths();
|
|
3847
|
-
if (options
|
|
3857
|
+
if (options.zen) {
|
|
3848
3858
|
consola.info("OpenCode Zen mode enabled");
|
|
3849
3859
|
state.zenMode = true;
|
|
3850
|
-
if (options
|
|
3851
|
-
state.zenApiKey = options
|
|
3860
|
+
if (options.zenApiKey) {
|
|
3861
|
+
state.zenApiKey = options.zenApiKey;
|
|
3852
3862
|
consola.info("Using provided Zen API key");
|
|
3853
3863
|
} else {
|
|
3854
|
-
const { setupZenApiKey, loadZenAuth } = await import("./auth-
|
|
3864
|
+
const { setupZenApiKey, loadZenAuth } = await import("./auth-g7psLP1B.js");
|
|
3855
3865
|
const existingAuth = await loadZenAuth();
|
|
3856
3866
|
if (existingAuth) {
|
|
3857
3867
|
state.zenApiKey = existingAuth.apiKey;
|
|
3858
3868
|
consola.info("Using existing Zen API key");
|
|
3859
3869
|
} else state.zenApiKey = await setupZenApiKey();
|
|
3860
3870
|
}
|
|
3861
|
-
const { cacheZenModels } = await import("./get-models-
|
|
3871
|
+
const { cacheZenModels } = await import("./get-models-onnSXkNI.js");
|
|
3862
3872
|
await cacheZenModels();
|
|
3863
3873
|
consola.info(`Available Zen models: \n${state.zenModels?.data.map((model) => `- ${model.id}`).join("\n")}`);
|
|
3864
|
-
} else if (options
|
|
3874
|
+
} else if (options.antigravity) {
|
|
3865
3875
|
consola.info("Google Antigravity mode enabled");
|
|
3866
3876
|
state.antigravityMode = true;
|
|
3867
|
-
const { loadAntigravityAuth, setupAntigravity, getCurrentAccount, hasApiKey, getApiKey
|
|
3868
|
-
if (options
|
|
3869
|
-
setOAuthCredentials(options
|
|
3877
|
+
const { loadAntigravityAuth, setupAntigravity, getCurrentAccount, hasApiKey, getApiKey, setOAuthCredentials } = await import("./auth-DreFwlx2.js");
|
|
3878
|
+
if (options.antigravityClientId && options.antigravityClientSecret) {
|
|
3879
|
+
setOAuthCredentials(options.antigravityClientId, options.antigravityClientSecret);
|
|
3870
3880
|
consola.info("Using provided OAuth credentials from CLI");
|
|
3871
3881
|
}
|
|
3872
3882
|
if (hasApiKey()) {
|
|
3873
3883
|
consola.info("Using Gemini API Key for authentication (from GEMINI_API_KEY)");
|
|
3874
|
-
consola.info(`API Key: ${getApiKey
|
|
3884
|
+
consola.info(`API Key: ${getApiKey()?.slice(0, 10) ?? ""}...`);
|
|
3875
3885
|
} else {
|
|
3876
3886
|
const existingAuth = await loadAntigravityAuth();
|
|
3877
3887
|
if (!existingAuth || existingAuth.accounts.length === 0) {
|
|
@@ -3893,17 +3903,17 @@ async function runServer(options$1) {
|
|
|
3893
3903
|
}
|
|
3894
3904
|
if (!await getCurrentAccount() && !hasApiKey()) throw new Error("No enabled Antigravity accounts available");
|
|
3895
3905
|
}
|
|
3896
|
-
const { getAntigravityModels
|
|
3897
|
-
const models = await getAntigravityModels
|
|
3906
|
+
const { getAntigravityModels } = await import("./get-models-PKzVxQmq.js");
|
|
3907
|
+
const models = await getAntigravityModels();
|
|
3898
3908
|
state.antigravityModels = models;
|
|
3899
3909
|
consola.info(`Available Antigravity models: \n${models.data.map((model) => `- ${model.id}`).join("\n")}`);
|
|
3900
3910
|
} else {
|
|
3901
3911
|
await cacheVSCodeVersion();
|
|
3902
|
-
if (options
|
|
3903
|
-
state.githubToken = options
|
|
3912
|
+
if (options.githubToken) {
|
|
3913
|
+
state.githubToken = options.githubToken;
|
|
3904
3914
|
consola.info("Using provided GitHub token");
|
|
3905
3915
|
try {
|
|
3906
|
-
const { getGitHubUser } = await import("./get-user-
|
|
3916
|
+
const { getGitHubUser } = await import("./get-user-CtEiwKow.js");
|
|
3907
3917
|
const user = await getGitHubUser();
|
|
3908
3918
|
consola.info(`Logged in as ${user.login}`);
|
|
3909
3919
|
} catch (error) {
|
|
@@ -3914,11 +3924,11 @@ async function runServer(options$1) {
|
|
|
3914
3924
|
try {
|
|
3915
3925
|
await setupCopilotToken();
|
|
3916
3926
|
} catch (error) {
|
|
3917
|
-
const { HTTPError
|
|
3918
|
-
if (error instanceof HTTPError
|
|
3927
|
+
const { HTTPError } = await import("./error-4DW6q2Mo.js");
|
|
3928
|
+
if (error instanceof HTTPError && error.response.status === 401) {
|
|
3919
3929
|
consola.error("Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked");
|
|
3920
|
-
const { clearGithubToken
|
|
3921
|
-
await clearGithubToken
|
|
3930
|
+
const { clearGithubToken } = await import("./token-B_0VZjlS.js");
|
|
3931
|
+
await clearGithubToken();
|
|
3922
3932
|
consola.info("Please restart to re-authenticate");
|
|
3923
3933
|
}
|
|
3924
3934
|
throw error;
|
|
@@ -3926,8 +3936,8 @@ async function runServer(options$1) {
|
|
|
3926
3936
|
await cacheModels();
|
|
3927
3937
|
consola.info(`Available models: \n${state.models?.data.map((model) => `- ${model.id}`).join("\n")}`);
|
|
3928
3938
|
}
|
|
3929
|
-
const serverUrl = `http://localhost:${options
|
|
3930
|
-
if (options
|
|
3939
|
+
const serverUrl = `http://localhost:${options.port}`;
|
|
3940
|
+
if (options.claudeCode) {
|
|
3931
3941
|
let modelList;
|
|
3932
3942
|
if (state.zenMode) modelList = state.zenModels?.data;
|
|
3933
3943
|
else if (state.antigravityMode) modelList = state.antigravityModels?.data;
|
|
@@ -3962,128 +3972,12 @@ async function runServer(options$1) {
|
|
|
3962
3972
|
consola.box(`🌐 Usage Viewer: https://imbuxiangnan-cyber.github.io/copilot-api-plus?endpoint=${serverUrl}/usage`);
|
|
3963
3973
|
serve({
|
|
3964
3974
|
fetch: server.fetch,
|
|
3965
|
-
port: options
|
|
3975
|
+
port: options.port
|
|
3966
3976
|
});
|
|
3967
3977
|
}
|
|
3968
|
-
const start = defineCommand({
|
|
3969
|
-
meta: {
|
|
3970
|
-
name: "start",
|
|
3971
|
-
description: "Start the Copilot API server"
|
|
3972
|
-
},
|
|
3973
|
-
args: {
|
|
3974
|
-
port: {
|
|
3975
|
-
alias: "p",
|
|
3976
|
-
type: "string",
|
|
3977
|
-
default: "4141",
|
|
3978
|
-
description: "Port to listen on"
|
|
3979
|
-
},
|
|
3980
|
-
verbose: {
|
|
3981
|
-
alias: "v",
|
|
3982
|
-
type: "boolean",
|
|
3983
|
-
default: false,
|
|
3984
|
-
description: "Enable verbose logging"
|
|
3985
|
-
},
|
|
3986
|
-
"account-type": {
|
|
3987
|
-
alias: "a",
|
|
3988
|
-
type: "string",
|
|
3989
|
-
default: "individual",
|
|
3990
|
-
description: "Account type to use (individual, business, enterprise)"
|
|
3991
|
-
},
|
|
3992
|
-
manual: {
|
|
3993
|
-
type: "boolean",
|
|
3994
|
-
default: false,
|
|
3995
|
-
description: "Enable manual request approval"
|
|
3996
|
-
},
|
|
3997
|
-
"rate-limit": {
|
|
3998
|
-
alias: "r",
|
|
3999
|
-
type: "string",
|
|
4000
|
-
description: "Rate limit in seconds between requests"
|
|
4001
|
-
},
|
|
4002
|
-
wait: {
|
|
4003
|
-
alias: "w",
|
|
4004
|
-
type: "boolean",
|
|
4005
|
-
default: false,
|
|
4006
|
-
description: "Wait instead of error when rate limit is hit. Has no effect if rate limit is not set"
|
|
4007
|
-
},
|
|
4008
|
-
"github-token": {
|
|
4009
|
-
alias: "g",
|
|
4010
|
-
type: "string",
|
|
4011
|
-
description: "Provide GitHub token directly (must be generated using the `auth` subcommand)"
|
|
4012
|
-
},
|
|
4013
|
-
"claude-code": {
|
|
4014
|
-
alias: "c",
|
|
4015
|
-
type: "boolean",
|
|
4016
|
-
default: false,
|
|
4017
|
-
description: "Generate a command to launch Claude Code with Copilot API config"
|
|
4018
|
-
},
|
|
4019
|
-
"show-token": {
|
|
4020
|
-
type: "boolean",
|
|
4021
|
-
default: false,
|
|
4022
|
-
description: "Show GitHub and Copilot tokens on fetch and refresh"
|
|
4023
|
-
},
|
|
4024
|
-
"proxy-env": {
|
|
4025
|
-
type: "boolean",
|
|
4026
|
-
default: false,
|
|
4027
|
-
description: "Initialize proxy from environment variables"
|
|
4028
|
-
},
|
|
4029
|
-
"api-key": {
|
|
4030
|
-
type: "string",
|
|
4031
|
-
description: "API keys for authentication"
|
|
4032
|
-
},
|
|
4033
|
-
zen: {
|
|
4034
|
-
alias: "z",
|
|
4035
|
-
type: "boolean",
|
|
4036
|
-
default: false,
|
|
4037
|
-
description: "Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)"
|
|
4038
|
-
},
|
|
4039
|
-
"zen-api-key": {
|
|
4040
|
-
type: "string",
|
|
4041
|
-
description: "OpenCode Zen API key (get from https://opencode.ai/zen)"
|
|
4042
|
-
},
|
|
4043
|
-
antigravity: {
|
|
4044
|
-
type: "boolean",
|
|
4045
|
-
default: false,
|
|
4046
|
-
description: "Enable Google Antigravity mode (proxy to Antigravity instead of GitHub Copilot)"
|
|
4047
|
-
},
|
|
4048
|
-
"antigravity-client-id": {
|
|
4049
|
-
type: "string",
|
|
4050
|
-
description: "Google OAuth Client ID for Antigravity (create at https://console.cloud.google.com/apis/credentials)"
|
|
4051
|
-
},
|
|
4052
|
-
"antigravity-client-secret": {
|
|
4053
|
-
type: "string",
|
|
4054
|
-
description: "Google OAuth Client Secret for Antigravity"
|
|
4055
|
-
}
|
|
4056
|
-
},
|
|
4057
|
-
run({ args }) {
|
|
4058
|
-
const rateLimitRaw = args["rate-limit"];
|
|
4059
|
-
const rateLimit = rateLimitRaw === void 0 ? void 0 : Number.parseInt(rateLimitRaw, 10);
|
|
4060
|
-
const apiKeyRaw = args["api-key"];
|
|
4061
|
-
let apiKeys;
|
|
4062
|
-
if (apiKeyRaw) apiKeys = Array.isArray(apiKeyRaw) ? apiKeyRaw : [apiKeyRaw];
|
|
4063
|
-
return runServer({
|
|
4064
|
-
port: Number.parseInt(args.port, 10),
|
|
4065
|
-
verbose: args.verbose,
|
|
4066
|
-
accountType: args["account-type"],
|
|
4067
|
-
manual: args.manual,
|
|
4068
|
-
rateLimit,
|
|
4069
|
-
rateLimitWait: args.wait,
|
|
4070
|
-
githubToken: args["github-token"],
|
|
4071
|
-
claudeCode: args["claude-code"],
|
|
4072
|
-
showToken: args["show-token"],
|
|
4073
|
-
proxyEnv: args["proxy-env"],
|
|
4074
|
-
apiKeys,
|
|
4075
|
-
zen: args.zen,
|
|
4076
|
-
zenApiKey: args["zen-api-key"],
|
|
4077
|
-
antigravity: args.antigravity,
|
|
4078
|
-
antigravityClientId: args["antigravity-client-id"],
|
|
4079
|
-
antigravityClientSecret: args["antigravity-client-secret"]
|
|
4080
|
-
});
|
|
4081
|
-
}
|
|
4082
|
-
});
|
|
4083
|
-
|
|
4084
3978
|
//#endregion
|
|
4085
3979
|
//#region src/main.ts
|
|
4086
|
-
|
|
3980
|
+
await runMain(defineCommand({
|
|
4087
3981
|
meta: {
|
|
4088
3982
|
name: "copilot-api-plus",
|
|
4089
3983
|
description: "A wrapper around GitHub Copilot API to make it OpenAI/Anthropic compatible. Fork with bug fixes and improvements."
|
|
@@ -4091,15 +3985,128 @@ const main = defineCommand({
|
|
|
4091
3985
|
subCommands: {
|
|
4092
3986
|
antigravity,
|
|
4093
3987
|
auth,
|
|
4094
|
-
start
|
|
3988
|
+
start: defineCommand({
|
|
3989
|
+
meta: {
|
|
3990
|
+
name: "start",
|
|
3991
|
+
description: "Start the Copilot API server"
|
|
3992
|
+
},
|
|
3993
|
+
args: {
|
|
3994
|
+
port: {
|
|
3995
|
+
alias: "p",
|
|
3996
|
+
type: "string",
|
|
3997
|
+
default: "4141",
|
|
3998
|
+
description: "Port to listen on"
|
|
3999
|
+
},
|
|
4000
|
+
verbose: {
|
|
4001
|
+
alias: "v",
|
|
4002
|
+
type: "boolean",
|
|
4003
|
+
default: false,
|
|
4004
|
+
description: "Enable verbose logging"
|
|
4005
|
+
},
|
|
4006
|
+
"account-type": {
|
|
4007
|
+
alias: "a",
|
|
4008
|
+
type: "string",
|
|
4009
|
+
default: "individual",
|
|
4010
|
+
description: "Account type to use (individual, business, enterprise)"
|
|
4011
|
+
},
|
|
4012
|
+
manual: {
|
|
4013
|
+
type: "boolean",
|
|
4014
|
+
default: false,
|
|
4015
|
+
description: "Enable manual request approval"
|
|
4016
|
+
},
|
|
4017
|
+
"rate-limit": {
|
|
4018
|
+
alias: "r",
|
|
4019
|
+
type: "string",
|
|
4020
|
+
description: "Rate limit in seconds between requests"
|
|
4021
|
+
},
|
|
4022
|
+
wait: {
|
|
4023
|
+
alias: "w",
|
|
4024
|
+
type: "boolean",
|
|
4025
|
+
default: false,
|
|
4026
|
+
description: "Wait instead of error when rate limit is hit. Has no effect if rate limit is not set"
|
|
4027
|
+
},
|
|
4028
|
+
"github-token": {
|
|
4029
|
+
alias: "g",
|
|
4030
|
+
type: "string",
|
|
4031
|
+
description: "Provide GitHub token directly (must be generated using the `auth` subcommand)"
|
|
4032
|
+
},
|
|
4033
|
+
"claude-code": {
|
|
4034
|
+
alias: "c",
|
|
4035
|
+
type: "boolean",
|
|
4036
|
+
default: false,
|
|
4037
|
+
description: "Generate a command to launch Claude Code with Copilot API config"
|
|
4038
|
+
},
|
|
4039
|
+
"show-token": {
|
|
4040
|
+
type: "boolean",
|
|
4041
|
+
default: false,
|
|
4042
|
+
description: "Show GitHub and Copilot tokens on fetch and refresh"
|
|
4043
|
+
},
|
|
4044
|
+
"proxy-env": {
|
|
4045
|
+
type: "boolean",
|
|
4046
|
+
default: false,
|
|
4047
|
+
description: "Initialize proxy from environment variables"
|
|
4048
|
+
},
|
|
4049
|
+
"api-key": {
|
|
4050
|
+
type: "string",
|
|
4051
|
+
description: "API keys for authentication"
|
|
4052
|
+
},
|
|
4053
|
+
zen: {
|
|
4054
|
+
alias: "z",
|
|
4055
|
+
type: "boolean",
|
|
4056
|
+
default: false,
|
|
4057
|
+
description: "Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)"
|
|
4058
|
+
},
|
|
4059
|
+
"zen-api-key": {
|
|
4060
|
+
type: "string",
|
|
4061
|
+
description: "OpenCode Zen API key (get from https://opencode.ai/zen)"
|
|
4062
|
+
},
|
|
4063
|
+
antigravity: {
|
|
4064
|
+
type: "boolean",
|
|
4065
|
+
default: false,
|
|
4066
|
+
description: "Enable Google Antigravity mode (proxy to Antigravity instead of GitHub Copilot)"
|
|
4067
|
+
},
|
|
4068
|
+
"antigravity-client-id": {
|
|
4069
|
+
type: "string",
|
|
4070
|
+
description: "Google OAuth Client ID for Antigravity (create at https://console.cloud.google.com/apis/credentials)"
|
|
4071
|
+
},
|
|
4072
|
+
"antigravity-client-secret": {
|
|
4073
|
+
type: "string",
|
|
4074
|
+
description: "Google OAuth Client Secret for Antigravity"
|
|
4075
|
+
}
|
|
4076
|
+
},
|
|
4077
|
+
run({ args }) {
|
|
4078
|
+
const rateLimitRaw = args["rate-limit"];
|
|
4079
|
+
const rateLimit = rateLimitRaw === void 0 ? void 0 : Number.parseInt(rateLimitRaw, 10);
|
|
4080
|
+
const apiKeyRaw = args["api-key"];
|
|
4081
|
+
let apiKeys;
|
|
4082
|
+
if (apiKeyRaw) apiKeys = Array.isArray(apiKeyRaw) ? apiKeyRaw : [apiKeyRaw];
|
|
4083
|
+
return runServer({
|
|
4084
|
+
port: Number.parseInt(args.port, 10),
|
|
4085
|
+
verbose: args.verbose,
|
|
4086
|
+
accountType: args["account-type"],
|
|
4087
|
+
manual: args.manual,
|
|
4088
|
+
rateLimit,
|
|
4089
|
+
rateLimitWait: args.wait,
|
|
4090
|
+
githubToken: args["github-token"],
|
|
4091
|
+
claudeCode: args["claude-code"],
|
|
4092
|
+
showToken: args["show-token"],
|
|
4093
|
+
proxyEnv: args["proxy-env"],
|
|
4094
|
+
apiKeys,
|
|
4095
|
+
zen: args.zen,
|
|
4096
|
+
zenApiKey: args["zen-api-key"],
|
|
4097
|
+
antigravity: args.antigravity,
|
|
4098
|
+
antigravityClientId: args["antigravity-client-id"],
|
|
4099
|
+
antigravityClientSecret: args["antigravity-client-secret"]
|
|
4100
|
+
});
|
|
4101
|
+
}
|
|
4102
|
+
}),
|
|
4095
4103
|
"check-usage": checkUsage,
|
|
4096
4104
|
debug,
|
|
4097
4105
|
logout,
|
|
4098
4106
|
proxy
|
|
4099
4107
|
}
|
|
4100
|
-
});
|
|
4101
|
-
await runMain(main);
|
|
4102
|
-
|
|
4108
|
+
}));
|
|
4103
4109
|
//#endregion
|
|
4104
|
-
export {
|
|
4110
|
+
export {};
|
|
4111
|
+
|
|
4105
4112
|
//# sourceMappingURL=main.js.map
|