UNPKG

route-claudecode

Version:

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

215 lines 8.43 kB
"use strict"; /** * 配置验证器 - 启动时验证和修正配置 */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateAndUpdateConfig = validateAndUpdateConfig; exports.quickHealthCheck = quickHealthCheck; const axios_1 = __importDefault(require("axios")); const logger_1 = require("./logger"); /** * 测试ModelScope模型的参数限制 */ async function testModelScopeModel(apiKey, model) { const endpoint = 'https://api-inference.modelscope.cn/v1/chat/completions'; const testMessage = [{ role: 'user', content: 'Hi' }]; const result = { model, maxTokens: null, supportsStreaming: false, responseTime: null, finishReason: null, error: null }; try { // 测试基本功能 const startTime = Date.now(); const basicResponse = await axios_1.default.post(endpoint, { model, messages: testMessage, max_tokens: 50, stream: false }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` }, timeout: 15000 }); result.responseTime = Date.now() - startTime; result.finishReason = basicResponse.data.choices?.[0]?.finish_reason; logger_1.logger.debug(`Model ${model} basic test passed`, { responseTime: result.responseTime, finishReason: result.finishReason }); // 测试max_tokens限制 - 二分查找最大值 let maxValidTokens = await findMaxTokens(apiKey, model, endpoint, testMessage); result.maxTokens = maxValidTokens; // 测试流式响应 try { const streamResponse = await axios_1.default.post(endpoint, { model, messages: testMessage, max_tokens: 20, stream: true }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` }, timeout: 10000, responseType: 'stream' }); result.supportsStreaming = streamResponse.status === 200; } catch (error) { logger_1.logger.warn(`Streaming test failed for ${model}`, { error: error.message }); } } catch (error) { result.error = error.response?.data?.error?.message || error.message; logger_1.logger.error(`Model test failed for ${model}`, { error: result.error }); } return result; } /** * 使用二分查找找到最大token限制 */ async function findMaxTokens(apiKey, model, endpoint, testMessage) { const testValues = [1000, 10000, 32768, 65536, 131072]; let maxValid = 50; for (const tokens of testValues) { try { await axios_1.default.post(endpoint, { model, messages: testMessage, max_tokens: tokens, stream: false }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` }, timeout: 10000 }); maxValid = tokens; logger_1.logger.debug(`max_tokens ${tokens} test passed for ${model}`); } catch (error) { logger_1.logger.debug(`max_tokens ${tokens} test failed for ${model}`, { error: error.response?.data?.error?.message || error.message }); break; } } return maxValid; } /** * 验证并更新配置 */ async function validateAndUpdateConfig(config) { logger_1.logger.info('Starting configuration validation...'); let configUpdated = false; // 查找ModelScope providers const modelScopeProviders = Object.entries(config.providers || {}) .filter(([id, provider]) => provider.endpoint?.includes('modelscope.cn')); if (modelScopeProviders.length === 0) { logger_1.logger.info('No ModelScope providers found, skipping validation'); return false; } for (const [providerId, provider] of modelScopeProviders) { logger_1.logger.info(`Validating provider: ${providerId}`); const providerConfig = provider; const apiKeys = Array.isArray(providerConfig.authentication?.credentials?.apiKey) ? providerConfig.authentication.credentials.apiKey : [providerConfig.authentication?.credentials?.apiKey].filter(Boolean); if (apiKeys.length === 0) { logger_1.logger.warn(`No API keys found for provider ${providerId}`); continue; } // 使用第一个API密钥进行测试 const testApiKey = apiKeys[0]; // 测试每个模型 const models = providerConfig.models || []; for (const model of models) { logger_1.logger.info(`Testing model: ${model}`); const testResult = await testModelScopeModel(testApiKey, model); if (testResult.error) { logger_1.logger.error(`Model ${model} validation failed`, { error: testResult.error }); continue; } // 更新maxTokens配置 if (testResult.maxTokens && providerConfig.maxTokens) { const currentMaxTokens = providerConfig.maxTokens[model]; if (currentMaxTokens && currentMaxTokens !== testResult.maxTokens) { logger_1.logger.info(`Updating maxTokens for ${model}`, { from: currentMaxTokens, to: testResult.maxTokens }); providerConfig.maxTokens[model] = testResult.maxTokens; configUpdated = true; } } logger_1.logger.info(`Model ${model} validation completed`, { maxTokens: testResult.maxTokens, supportsStreaming: testResult.supportsStreaming, responseTime: testResult.responseTime, finishReason: testResult.finishReason }); } } if (configUpdated) { logger_1.logger.info('Configuration updated based on validation results'); } else { logger_1.logger.info('No configuration changes needed'); } return configUpdated; } /** * 快速健康检查 - 只测试基本连接 */ async function quickHealthCheck(config) { logger_1.logger.info('Performing quick health check...'); const modelScopeProviders = Object.entries(config.providers || {}) .filter(([id, provider]) => provider.endpoint?.includes('modelscope.cn')); if (modelScopeProviders.length === 0) { return true; // 没有ModelScope provider,跳过检查 } for (const [providerId, provider] of modelScopeProviders) { const providerConfig = provider; const apiKeys = Array.isArray(providerConfig.authentication?.credentials?.apiKey) ? providerConfig.authentication.credentials.apiKey : [providerConfig.authentication?.credentials?.apiKey].filter(Boolean); if (apiKeys.length === 0) continue; try { const response = await axios_1.default.post('https://api-inference.modelscope.cn/v1/chat/completions', { model: providerConfig.models?.[0] || 'ZhipuAI/GLM-4.5', messages: [{ role: 'user', content: 'Hi' }], max_tokens: 10, stream: false }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKeys[0]}` }, timeout: 10000 }); if (response.status === 200) { logger_1.logger.info(`Health check passed for provider ${providerId}`); return true; } } catch (error) { logger_1.logger.warn(`Health check failed for provider ${providerId}`, { error: error.response?.data?.error?.message || error.message }); } } return false; } //# sourceMappingURL=config-validator.js.map