gravityyy-proxyyy / src /index.js
bardd's picture
Fix gemini-3.1-pro-high by routing to pro-low with thinkingLevel high.
4badc3b
Raw
History Blame Contribute Delete
8.67 kB
/**
* Antigravity Claude Proxy
* Entry point - starts the proxy server
*/
// Initialize proxy support BEFORE any other imports that may use fetch
import './utils/proxy.js';
import app, { accountManager } from './server.js';
import { DEFAULT_PORT } from './constants.js';
import { logger } from './utils/logger.js';
import { config } from './config.js';
import { getStrategyLabel, STRATEGY_NAMES, DEFAULT_STRATEGY } from './account-manager/strategies/index.js';
import { getPackageVersion } from './utils/helpers.js';
import path from 'path';
import os from 'os';
const packageVersion = getPackageVersion();
// Parse command line arguments
const args = process.argv.slice(2);
const isDebug = args.includes('--debug') || args.includes('--dev-mode') || process.env.DEBUG === 'true' || process.env.DEV_MODE === 'true';
const isFallbackEnabled = args.includes('--fallback') || process.env.FALLBACK === 'true';
// Parse --strategy flag (format: --strategy=sticky or --strategy sticky)
let strategyOverride = null;
for (let i = 0; i < args.length; i++) {
if (args[i].startsWith('--strategy=')) {
strategyOverride = args[i].split('=')[1];
} else if (args[i] === '--strategy' && args[i + 1]) {
strategyOverride = args[i + 1];
}
}
// Validate strategy
if (strategyOverride && !STRATEGY_NAMES.includes(strategyOverride.toLowerCase())) {
logger.warn(`[Startup] Invalid strategy "${strategyOverride}". Valid options: ${STRATEGY_NAMES.join(', ')}. Using default.`);
strategyOverride = null;
}
// Initialize logger and devMode
logger.setDebug(isDebug);
if (isDebug) {
config.devMode = true;
config.debug = true;
logger.debug('Developer mode enabled');
}
if (isFallbackEnabled) {
logger.info('Model fallback mode enabled');
}
if (!config.apiKey) {
logger.error('[Startup] PROXY_API_KEY is not set. All /v1/* requests will be rejected until it is configured.');
}
// Export fallback flag for server to use
export const FALLBACK_ENABLED = isFallbackEnabled;
const PORT = process.env.PORT || DEFAULT_PORT;
const HOST = process.env.HOST || '0.0.0.0';
if (process.env.HOST) {
logger.info(`[Startup] Using HOST environment variable: ${process.env.HOST}`);
}
// Home directory for account storage
const HOME_DIR = os.homedir();
const CONFIG_DIR = path.join(HOME_DIR, '.antigravity-claude-proxy');
const server = app.listen(PORT, HOST, () => {
// Get actual bound address
const address = server.address();
const boundHost = typeof address === 'string' ? address : address.address;
const boundPort = typeof address === 'string' ? null : address.port;
// Clear console for a clean start
console.clear();
const border = 'β•‘';
// align for 2-space indent (60 chars), align4 for 4-space indent (58 chars)
const align = (text) => text + ' '.repeat(Math.max(0, 60 - text.length));
const align4 = (text) => text + ' '.repeat(Math.max(0, 58 - text.length));
// Build Control section dynamically
const strategyOptions = `(${STRATEGY_NAMES.join('/')})`;
const strategyLine2 = ' ' + strategyOptions;
let controlSection = 'β•‘ Control: β•‘\n';
controlSection += 'β•‘ --strategy=<s> Set account selection strategy β•‘\n';
controlSection += `${border} ${align(strategyLine2)}${border}\n`;
if (!isDebug) {
controlSection += 'β•‘ --dev-mode Enable developer mode β•‘\n';
}
if (!isFallbackEnabled) {
controlSection += 'β•‘ --fallback Enable model fallback on quota exhaust β•‘\n';
}
controlSection += 'β•‘ Ctrl+C Stop server β•‘';
// Get the strategy label (accountManager will be initialized by now)
const strategyLabel = accountManager.getStrategyLabel();
// Build status section - always show strategy, plus any active modes
let statusSection = 'β•‘ β•‘\n';
statusSection += 'β•‘ Active Modes: β•‘\n';
statusSection += `${border} ${align4(`βœ“ Strategy: ${strategyLabel}`)}${border}\n`;
if (isDebug) {
statusSection += 'β•‘ βœ“ Developer mode enabled β•‘\n';
}
if (isFallbackEnabled) {
statusSection += 'β•‘ βœ“ Model fallback enabled β•‘\n';
}
if (process.env.CLAUDE_CONFIG_PATH) {
statusSection += `${border} ${align4(`βœ“ Claude config: ${process.env.CLAUDE_CONFIG_PATH}`)}${border}\n`;
}
const environmentSection = `β•‘ Environment Variables: β•‘
β•‘ PORT Server port (default: 8080) β•‘
β•‘ PROXY_API_KEY OpenAI-compatible bearer key β•‘
β•‘ ACCOUNT_CONFIG_PATH Account storage path β•‘
β•‘ ENABLE_WEBUI Set false for headless mode β•‘
β•‘ HOST Bind address (default: 0.0.0.0) β•‘
β•‘ HTTP_PROXY Route requests through a proxy β•‘
β•‘ CLAUDE_CONFIG_PATH Path to .claude dir (for systemd) β•‘
β•‘ See README.md for detailed configuration examples β•‘`
logger.log(`
╔══════════════════════════════════════════════════════════════╗
β•‘ Antigravity Claude Proxy Server v${packageVersion} β•‘
╠══════════════════════════════════════════════════════════════╣
β•‘ β•‘
${border} ${align(`Server and WebUI running at: http://${HOST === '0.0.0.0' ? 'localhost' : HOST}:${PORT}`)}${border}
${border} ${align(`Bound to: ${boundHost}:${boundPort}`)}${border}
${statusSection}β•‘ β•‘
${controlSection}
β•‘ β•‘
β•‘ Endpoints: β•‘
β•‘ POST /v1/messages - Anthropic Messages API β•‘
β•‘ POST /v1/chat/completions - OpenAI Chat Completions β•‘
β•‘ GET /v1/models - List available models β•‘
β•‘ GET /health - Health check β•‘
β•‘ GET /account-limits - Account status & quotas β•‘
β•‘ POST /refresh-token - Force token refresh β•‘
β•‘ β•‘
${border} ${align(`Configuration:`)}${border}
${border} ${align4(`Storage: ${CONFIG_DIR}`)}${border}
β•‘ β•‘
β•‘ Usage with Claude Code: β•‘
${border} ${align4(`export ANTHROPIC_BASE_URL=http://localhost:${PORT}`)}${border}
${border} ${align4(`export ANTHROPIC_API_KEY=${config.apiKey || 'dummy'}`)}${border}
β•‘ claude β•‘
β•‘ β•‘
β•‘ Add Google accounts: β•‘
β•‘ npm run accounts β•‘
β•‘ β•‘
β•‘ Prerequisites (if no accounts configured): β•‘
β•‘ - Antigravity must be running β•‘
β•‘ - Have a chat panel open in Antigravity β•‘
β•‘ β•‘
${environmentSection}
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
`);
logger.success(`Server started successfully on port ${PORT}`);
if (isDebug) {
logger.warn('Running in DEVELOPER mode - verbose logs enabled');
}
});
// Graceful shutdown
const shutdown = () => {
logger.info('Shutting down server...');
server.close(() => {
logger.success('Server stopped');
process.exit(0);
});
// Force close if it takes too long
setTimeout(() => {
logger.error('Could not close connections in time, forcefully shutting down');
process.exit(1);
}, 10000);
};
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);