hedgequantx 2.6.103 → 2.6.105
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/package.json
CHANGED
|
@@ -271,18 +271,92 @@ const stop = async () => {
|
|
|
271
271
|
});
|
|
272
272
|
};
|
|
273
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Check if config has correct management key (plain text, not hashed)
|
|
276
|
+
* CLIProxyAPI expects plain text key in config, it does bcrypt hashing internally
|
|
277
|
+
* @returns {boolean} true if config is correct, false if needs update
|
|
278
|
+
*/
|
|
279
|
+
const isConfigValid = () => {
|
|
280
|
+
if (!fs.existsSync(PROXY_CONFIG)) return false;
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
const config = fs.readFileSync(PROXY_CONFIG, 'utf8');
|
|
284
|
+
|
|
285
|
+
// Check if management key section exists
|
|
286
|
+
if (!config.includes('remote-management:') || !config.includes('secret-key:')) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Check if key is hashed (bcrypt hashes start with $2a$, $2b$, or $2y$)
|
|
291
|
+
// Plain text key should be 'hqx-mgmt-key', not a bcrypt hash
|
|
292
|
+
if (config.includes('$2a$') || config.includes('$2b$') || config.includes('$2y$')) {
|
|
293
|
+
return false; // Config has hashed key, needs to be plain text
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Check if it has our expected management key
|
|
297
|
+
if (!config.includes(MANAGEMENT_KEY)) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return true;
|
|
302
|
+
} catch (e) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Rewrite config file with correct settings
|
|
309
|
+
*/
|
|
310
|
+
const rewriteConfig = () => {
|
|
311
|
+
const config = `port: ${PROXY_PORT}
|
|
312
|
+
auth-dir: "${PROXY_AUTH_DIR}"
|
|
313
|
+
api-keys:
|
|
314
|
+
- "${API_KEY}"
|
|
315
|
+
remote-management:
|
|
316
|
+
secret-key: "${MANAGEMENT_KEY}"
|
|
317
|
+
allow-remote-management: false
|
|
318
|
+
request-retry: 3
|
|
319
|
+
quota-exceeded:
|
|
320
|
+
switch-project: true
|
|
321
|
+
switch-preview-model: true
|
|
322
|
+
`;
|
|
323
|
+
|
|
324
|
+
// Ensure directory exists
|
|
325
|
+
if (!fs.existsSync(PROXY_DIR)) {
|
|
326
|
+
fs.mkdirSync(PROXY_DIR, { recursive: true });
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
fs.writeFileSync(PROXY_CONFIG, config);
|
|
330
|
+
};
|
|
331
|
+
|
|
274
332
|
/**
|
|
275
333
|
* Ensure CLIProxyAPI is installed and running
|
|
276
334
|
* @param {Function} onProgress - Progress callback
|
|
277
335
|
*/
|
|
278
336
|
const ensureRunning = async (onProgress = () => {}) => {
|
|
337
|
+
// Check if config needs to be fixed (e.g., has hashed key instead of plain text)
|
|
338
|
+
const configValid = isConfigValid();
|
|
339
|
+
|
|
279
340
|
if (await isRunning()) {
|
|
341
|
+
if (!configValid) {
|
|
342
|
+
// Config is invalid but proxy is running - need to restart with correct config
|
|
343
|
+
onProgress('Updating proxy configuration...');
|
|
344
|
+
rewriteConfig();
|
|
345
|
+
await stop();
|
|
346
|
+
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for process to fully stop
|
|
347
|
+
onProgress('Restarting proxy with updated config...');
|
|
348
|
+
await start();
|
|
349
|
+
}
|
|
280
350
|
return true;
|
|
281
351
|
}
|
|
282
352
|
|
|
283
353
|
if (!isInstalled()) {
|
|
284
354
|
onProgress('Installing AI proxy (one-time setup)...');
|
|
285
355
|
await install(onProgress);
|
|
356
|
+
} else if (!configValid) {
|
|
357
|
+
// Binary exists but config is invalid - fix it
|
|
358
|
+
onProgress('Fixing proxy configuration...');
|
|
359
|
+
rewriteConfig();
|
|
286
360
|
}
|
|
287
361
|
|
|
288
362
|
onProgress('Starting AI proxy...');
|
|
@@ -393,12 +467,14 @@ const managementRequest = (method, endpoint, body = null) => {
|
|
|
393
467
|
const getAuthUrl = async (provider) => {
|
|
394
468
|
await ensureRunning();
|
|
395
469
|
|
|
470
|
+
// Use is_webui=true to start the callback server on port 54545
|
|
471
|
+
// Without this, CLIProxyAPI generates the URL but doesn't listen for callbacks
|
|
396
472
|
const endpoints = {
|
|
397
|
-
anthropic: '/v0/management/anthropic-auth-url',
|
|
398
|
-
openai: '/v0/management/codex-auth-url',
|
|
399
|
-
gemini: '/v0/management/gemini-cli-auth-url',
|
|
400
|
-
qwen: '/v0/management/qwen-auth-url',
|
|
401
|
-
iflow: '/v0/management/iflow-auth-url'
|
|
473
|
+
anthropic: '/v0/management/anthropic-auth-url?is_webui=true',
|
|
474
|
+
openai: '/v0/management/codex-auth-url?is_webui=true',
|
|
475
|
+
gemini: '/v0/management/gemini-cli-auth-url?is_webui=true',
|
|
476
|
+
qwen: '/v0/management/qwen-auth-url?is_webui=true',
|
|
477
|
+
iflow: '/v0/management/iflow-auth-url?is_webui=true'
|
|
402
478
|
};
|
|
403
479
|
|
|
404
480
|
const endpoint = endpoints[provider];
|