// Import required modules const express = require('express'); const morgan = require('morgan'); const { createProxyMiddleware } = require('http-proxy-middleware'); const axios = require('axios'); const url = require('url'); const app = express(); // Middleware for logging requests app.use(morgan('dev')); // Middleware to parse JSON bodies app.use(express.json()); // Global proxy pool let proxyPool = process.env.PROXY ? process.env.PROXY.split(',').map(p => p.trim()) : []; console.log('Initial proxy pool:', proxyPool); // Function to get a random proxy function getRandomProxy() { if (proxyPool.length === 0) return null; const randomIndex = Math.floor(Math.random() * proxyPool.length); const proxyUrl = proxyPool[randomIndex]; const parsedUrl = url.parse(proxyUrl); return { host: parsedUrl.hostname, port: parsedUrl.port || 80, auth: parsedUrl.auth ? { username: parsedUrl.auth.split(':')[0], password: parsedUrl.auth.split(':')[1] } : undefined }; } // Configure axios proxy function configureAxiosProxy() { const proxy = getRandomProxy(); if (proxy) { axios.defaults.proxy = proxy; console.log(`Axios using proxy: ${proxy.host}:${proxy.port}`); } else { delete axios.defaults.proxy; console.log('No proxy available for axios'); } } // Update proxy pool from external API async function updateProxyPool() { const proxyApiUrl = process.env.PROXY_API_URL || 'http://example.com/api/proxies'; try { const response = await axios.get(proxyApiUrl); const newProxies = response.data.proxies || []; if (newProxies.length > 0) { proxyPool = newProxies; console.log('Proxy pool updated:', proxyPool); configureAxiosProxy(); } else { console.warn('No proxies received from API'); } } catch (error) { console.error('Failed to update proxy pool:', error.message); } } // Periodically update proxy pool const updateInterval = parseInt(process.env.PROXY_UPDATE_INTERVAL) || 300; // Default 5 minutes if (updateInterval > 0) { setInterval(updateProxyPool, updateInterval * 1000); console.log(`Proxy pool will update every ${updateInterval} seconds`); updateProxyPool(); // Initial update } // Models API app.get('/hf/v1/models', (req, res) => { const models = { "object": "list", "data": [ { "id": "claude-3.5-sonnet", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4o", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-opus", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-3.5-turbo", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4-turbo-2024-04-09", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4o-128k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-1.5-flash-500k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-haiku-200k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-5-sonnet-200k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-5-sonnet-20241022", "object": "model", "created": 1706745938, " owned_by": "cursor" }, { "id": "gpt-4o-mini", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "o1-mini", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "o1-preview", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "o1", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3.5-haiku", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-exp-1206", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-2.0-flash-thinking-exp", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-2.0-flash-exp", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "deepseek-v3", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "deepseek-r1", "object": "model", "created": 1706745938, "owned_by": "cursor" } ] }; res.json(models); }); // Proxy for chat completions app.use('/hf/v1/chat/completions', (req, res, next) => { const proxy = getRandomProxy(); const middleware = createProxyMiddleware({ target: 'http://localhost:3010/v1/chat/completions', // Replace with actual target service changeOrigin: true, timeout: 30000, proxyTimeout: 30000, onProxyReq: (proxyReq, req, res) => { if (req.body) { const bodyData = JSON.stringify(req.body); proxyReq.setHeader('Content-Type', 'application/json'); proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); proxyReq.write(bodyData); proxyReq.end(); } }, onError: (err, req, res) => { console.error('Proxy error:', err); res.status(500).send('Proxy error occurred'); } }); if (proxy) { console.log(`Request proxied via ${proxy.host}:${proxy.port}`); } else { console.log('No proxy available, direct connection'); } middleware(req, res, next); }); // Home page with interactive frontend app.get('/', (req, res) => { const htmlContent = ` Cursor To OpenAI

Cursor To OpenAI Server

高性能 AI 模型代理服务

配置信息

聊天来源
自定义(兼容 OpenAI)
自定义端点(基本URL)
自定义API密钥
抓取的Cursor Cookie,格式为user_...

与 AI 互动

支持的模型列表

`; res.send(htmlContent); }); // Start the server and configure initial axios proxy configureAxiosProxy(); const port = process.env.HF_PORT || 7860; app.listen(port, () => { console.log(`HF Proxy server is running at PORT: ${port}`); });