UNPKG

route-claudecode

Version:

Advanced routing and transformation system for Claude Code outputs to multiple AI providers

214 lines 7.83 kB
"use strict"; /** * Route Setup Module * * 负责设置所有HTTP路由和中间件 * 按照细菌式编程原则:小巧、模块化、自包含 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.RouteSetup = void 0; exports.createRouteSetup = createRouteSetup; class RouteSetup { deps; constructor(deps) { this.deps = deps; } /** * 设置所有路由 */ setupRoutes() { this.setupHealthRoutes(); this.setupAdminRoutes(); this.setupMessageRoutes(); this.setupCompatibilityRoutes(); this.deps.logger.info('All routes configured successfully'); } /** * 设置健康检查路由 */ setupHealthRoutes() { // 基础健康检查 this.deps.fastify.get('/health', async (request, reply) => { return this.deps.healthHandler.handleHealthCheck(request, reply); }); // 详细状态检查 this.deps.fastify.get('/status', async (request, reply) => { return this.deps.healthHandler.handleStatusCheck(request, reply); }); } /** * 设置管理API路由 */ setupAdminRoutes() { // 系统统计 this.deps.fastify.get('/api/stats', async (request, reply) => { return this.deps.adminHandler.handleApiStats(request, reply); }); // 简化统计 this.deps.fastify.get('/stats', async (request, reply) => { return this.deps.adminHandler.handleStats(request, reply); }); // 双重统计 this.deps.fastify.get('/dual-stats', async (request, reply) => { return this.deps.adminHandler.handleDualStats(request, reply); }); // 失败记录 this.deps.fastify.get('/api/failures', async (request, reply) => { return this.deps.adminHandler.handleFailures(request, reply); }); // Provider管理 this.deps.fastify.post('/api/providers/:providerId/disable', async (request, reply) => { return this.deps.adminHandler.handleProviderDisable(request, reply); }); this.deps.fastify.post('/api/providers/:providerId/enable', async (request, reply) => { return this.deps.adminHandler.handleProviderEnable(request, reply); }); this.deps.fastify.get('/api/providers/temporary-disabled', async (request, reply) => { return this.deps.adminHandler.handleTemporaryDisabled(request, reply); }); // 系统控制 this.deps.fastify.post('/shutdown', async (request, reply) => { return this.deps.adminHandler.handleShutdown(request, reply); }); // OpenAI客户端状态(兼容性) this.deps.fastify.get('/api/openai-client-status', async (request, reply) => { return this.handleOpenAIClientStatus(request, reply); }); // 错误诊断 this.deps.fastify.get('/api/error-diagnostics', async (request, reply) => { return this.deps.adminHandler.handleErrorDiagnostics(request, reply); }); } /** * 设置消息处理路由 */ setupMessageRoutes() { // Anthropic格式的消息接口 this.deps.fastify.post('/v1/messages', async (request, reply) => { return this.deps.messagesHandler.handleMessagesRequest(request, reply); }); // Token计数接口 this.deps.fastify.post('/v1/messages/count_tokens', async (request, reply) => { return this.deps.adminHandler.handleCountTokens(request, reply); }); } /** * 设置兼容性路由 */ setupCompatibilityRoutes() { // OpenAI兼容接口(转发到messages处理器) this.deps.fastify.post('/v1/chat/completions', async (request, reply) => { // 将OpenAI格式请求转换为Anthropic格式,然后使用相同的处理器 return this.handleOpenAICompatibility(request, reply); }); } /** * 设置请求钩子 */ setupHooks() { // 请求前钩子 this.deps.fastify.addHook('onRequest', async (request, reply) => { const requestId = this.generateRequestId(); request.requestId = requestId; request.startTime = Date.now(); this.deps.logger.info('Incoming request', { method: request.method, url: request.url, requestId }, requestId, 'request'); }); // 响应后钩子 this.deps.fastify.addHook('onResponse', async (request, reply) => { const requestId = request.requestId; const startTime = request.startTime || Date.now(); const responseTime = Date.now() - startTime; this.deps.logger.info('Request completed', { method: request.method, url: request.url, statusCode: reply.statusCode, responseTime: `${responseTime}ms`, requestId }, requestId, 'response'); }); this.deps.logger.info('Request hooks configured'); } /** * 处理OpenAI客户端状态请求 */ async handleOpenAIClientStatus(request, reply) { try { // 简化的OpenAI客户端状态响应 const status = { status: 'operational', timestamp: new Date().toISOString(), port: this.deps.config.server.port, version: '2.8.0', openaiCompatible: true }; reply.send(status); } catch (error) { this.deps.logger.error('OpenAI client status failed', error); reply.code(500).send({ status: 'error', message: 'Status check failed' }); } } /** * 处理OpenAI兼容性请求 */ async handleOpenAICompatibility(request, reply) { try { // 这里应该将OpenAI格式转换为Anthropic格式 // 为了简化,暂时直接转发给messages处理器 this.deps.logger.info('Converting OpenAI request to Anthropic format', { originalUrl: request.url }, request.requestId, 'compatibility'); // 转换请求格式(简化实现) const openaiBody = request.body; const anthropicBody = this.convertOpenAIToAnthropic(openaiBody); // 修改请求体 request.body = anthropicBody; // 使用messages处理器处理 return this.deps.messagesHandler.handleMessagesRequest(request, reply); } catch (error) { this.deps.logger.error('OpenAI compatibility conversion failed', error); reply.code(500).send({ error: { type: 'internal_server_error', message: 'Request format conversion failed' } }); } } /** * 简化的OpenAI到Anthropic格式转换 */ convertOpenAIToAnthropic(openaiBody) { // 简化的转换逻辑 return { model: openaiBody.model, messages: openaiBody.messages || [], max_tokens: openaiBody.max_tokens || 1024, stream: openaiBody.stream || false, tools: openaiBody.tools, tool_choice: openaiBody.tool_choice }; } /** * 生成请求ID */ generateRequestId() { return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } } exports.RouteSetup = RouteSetup; /** * 创建Route Setup实例的工厂函数 */ function createRouteSetup(deps) { return new RouteSetup(deps); } //# sourceMappingURL=route-setup.js.map