Skip to main content
Glama
config-validator.ts5.4 kB
/** * 配置验证工具 * 验证AI配置文件的完整性和有效性 */ import { loadAIProvidersConfig, getAIClientByModelName, } from './ai-client-adapter.js'; import { AIModelConfig } from './types.js'; export interface ConfigValidationResult { isValid: boolean; errors: string[]; warnings: string[]; availableModels: string[]; providers: string[]; } /** * 验证AI配置 */ export async function validateAIConfig(): Promise<ConfigValidationResult> { const result: ConfigValidationResult = { isValid: true, errors: [], warnings: [], availableModels: [], providers: [], }; try { // 加载配置 const config = loadAIProvidersConfig(true); // 强制重新加载 // 验证基本结构 if (!config.providers || !Array.isArray(config.providers)) { result.isValid = false; result.errors.push('配置文件中缺少 providers 数组'); return result; } if (config.providers.length === 0) { result.isValid = false; result.errors.push('配置文件中没有配置任何AI提供商'); return result; } // 验证每个提供商 for (const provider of config.providers) { result.providers.push(provider.provider); if (!provider.provider) { result.isValid = false; result.errors.push('提供商配置缺少 provider 字段'); continue; } if (!provider.models || !Array.isArray(provider.models)) { result.isValid = false; result.errors.push(`提供商 ${provider.provider} 缺少 models 数组`); continue; } if (provider.models.length === 0) { result.warnings.push(`提供商 ${provider.provider} 没有配置任何模型`); continue; } // 验证每个模型 for (const model of provider.models) { const modelValidation = validateModelConfig(model, provider.provider); if (!modelValidation.isValid) { result.isValid = false; result.errors.push(...modelValidation.errors); } else { result.availableModels.push(model.model); } } } // 验证是否有重复的模型名称 const modelNames = result.availableModels; const duplicates = modelNames.filter( (name, index) => modelNames.indexOf(name) !== index ); if (duplicates.length > 0) { result.warnings.push(`发现重复的模型名称: ${duplicates.join(', ')}`); } // 验证默认模型是否可用 if (config.defaultModels) { for (const [purpose, modelName] of Object.entries(config.defaultModels)) { if (!result.availableModels.includes(modelName)) { result.warnings.push( `默认模型 ${modelName} (用途: ${purpose}) 在配置中不可用` ); } } } // 验证模型用途映射 if (config.modelPurposes) { for (const [modelName] of Object.entries(config.modelPurposes)) { if (!result.availableModels.includes(modelName)) { result.warnings.push( `模型用途映射中的模型 ${modelName} 在配置中不可用` ); } } } return result; } catch (error) { result.isValid = false; result.errors.push( `配置加载失败: ${error instanceof Error ? error.message : String(error)}` ); return result; } } /** * 验证单个模型配置 */ function validateModelConfig( model: AIModelConfig, provider: string ): { isValid: boolean; errors: string[] } { const errors: string[] = []; if (!model.model) { errors.push(`提供商 ${provider} 的模型缺少 model 字段`); } if (!model.title) { errors.push(`模型 ${model.model} 缺少 title 字段`); } if (!model.baseURL) { errors.push(`模型 ${model.model} 缺少 baseURL 字段`); } if (!model.apiKey && provider !== 'ollama') { errors.push(`模型 ${model.model} 缺少 apiKey 字段`); } if (!Array.isArray(model.features)) { errors.push(`模型 ${model.model} 的 features 字段必须是数组`); } return { isValid: errors.length === 0, errors, }; } /** * 测试AI客户端连接 */ export async function testAIConnection(modelName: string): Promise<{ success: boolean; error?: string; responseTime?: number; }> { try { const startTime = Date.now(); // 尝试创建AI客户端 getAIClientByModelName(modelName); const responseTime = Date.now() - startTime; return { success: true, responseTime, }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), }; } } /** * 获取配置摘要 */ export function getConfigSummary(): { totalProviders: number; totalModels: number; providers: Array<{ name: string; modelCount: number; models: string[]; }>; } { try { const config = loadAIProvidersConfig(); const providers = config.providers.map(provider => ({ name: provider.provider, modelCount: provider.models.length, models: provider.models.map(m => m.model), })); return { totalProviders: providers.length, totalModels: providers.reduce((sum, p) => sum + p.modelCount, 0), providers, }; } catch (error) { return { totalProviders: 0, totalModels: 0, providers: [], }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lyw405/mcp-garendesign'

If you have feedback or need assistance with the MCP directory API, please join our Discord server