cursor2api / src /index.ts
Tyb7654's picture
Upload 9 files
02d34ae verified
/**
* Cursor2API v2 - ๅ…ฅๅฃ
*
* ๅฐ† Cursor ๆ–‡ๆกฃ้กตๅ…่ดน AI ๆŽฅๅฃไปฃ็†ไธบ Anthropic Messages API
* ้€š่ฟ‡ๆ็คบ่ฏๆณจๅ…ฅ่ฎฉ Claude Code ๆ‹ฅๆœ‰ๅฎŒๆ•ดๅทฅๅ…ท่ฐƒ็”จ่ƒฝๅŠ›
*/
import 'dotenv/config';
import express from 'express';
import { getConfig } from './config.js';
import { handleMessages, listModels, countTokens } from './handler.js';
import { handleOpenAIChatCompletions } from './openai-handler.js';
const app = express();
const config = getConfig();
// ่งฃๆž JSON body๏ผˆๅขžๅคง้™ๅˆถไปฅๆ”ฏๆŒ base64 ๅ›พ็‰‡๏ผŒๅ•ๅผ ๅ›พ็‰‡ๅฏ่พพ 10MB+๏ผ‰
app.use(express.json({ limit: '50mb' }));
// CORS
app.use((_req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.header('Access-Control-Allow-Headers', '*');
if (_req.method === 'OPTIONS') {
res.sendStatus(200);
return;
}
next();
});
// ==================== ่ทฏ็”ฑ ====================
// Anthropic Messages API
app.post('/v1/messages', handleMessages);
app.post('/messages', handleMessages);
// OpenAI Chat Completions API๏ผˆๅ…ผๅฎน๏ผ‰
app.post('/v1/chat/completions', handleOpenAIChatCompletions);
app.post('/chat/completions', handleOpenAIChatCompletions);
// Token ่ฎกๆ•ฐ
app.post('/v1/messages/count_tokens', countTokens);
app.post('/messages/count_tokens', countTokens);
// OpenAI ๅ…ผๅฎนๆจกๅž‹ๅˆ—่กจ
app.get('/v1/models', listModels);
// ๅฅๅบทๆฃ€ๆŸฅ
app.get('/health', (_req, res) => {
res.json({ status: 'ok', version: '2.3.2' });
});
// ๆ น่ทฏๅพ„
app.get('/', (_req, res) => {
res.json({
name: 'cursor2api',
version: '2.3.2',
description: 'Cursor Docs AI โ†’ Anthropic & OpenAI API Proxy',
endpoints: {
anthropic_messages: 'POST /v1/messages',
openai_chat: 'POST /v1/chat/completions',
models: 'GET /v1/models',
health: 'GET /health',
},
usage: {
claude_code: 'export ANTHROPIC_BASE_URL=http://localhost:' + config.port,
openai_compatible: 'OPENAI_BASE_URL=http://localhost:' + config.port + '/v1',
},
});
});
// ==================== ๅฏๅŠจ ====================
app.listen(config.port, () => {
console.log('');
console.log(' โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—');
console.log(' โ•‘ Cursor2API v2.3.2 โ•‘');
console.log(' โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ');
console.log(` โ•‘ Server: http://localhost:${config.port} โ•‘`);
console.log(' โ•‘ Model: ' + config.cursorModel.padEnd(26) + 'โ•‘');
console.log(' โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ');
console.log(' โ•‘ API Endpoints: โ•‘');
console.log(' โ•‘ โ€ข Anthropic: /v1/messages โ•‘');
console.log(' โ•‘ โ€ข OpenAI: /v1/chat/completions โ•‘');
console.log(' โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ');
console.log(' โ•‘ Claude Code: โ•‘');
console.log(` โ•‘ export ANTHROPIC_BASE_URL= โ•‘`);
console.log(` โ•‘ http://localhost:${config.port} โ•‘`);
console.log(' โ•‘ OpenAI ๅ…ผๅฎน: โ•‘');
console.log(` โ•‘ OPENAI_BASE_URL= โ•‘`);
console.log(` โ•‘ http://localhost:${config.port}/v1 โ•‘`);
console.log(' โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
console.log('');
});