UNPKG

woaru

Version:

Universal Project Setup Autopilot - Analyze and automatically configure development tools for ANY programming language

254 lines 10.3 kB
import { ConfigManager } from '../config/ConfigManager.js'; export class ConfigLoader { static instance; config = null; constructor() { } static getInstance() { if (!ConfigLoader.instance) { ConfigLoader.instance = new ConfigLoader(); } return ConfigLoader.instance; } /** * Load AI review configuration from global ~/.woaru/config/ai_config.json */ async loadConfig(_projectPath) { if (this.config) { return this.config; } try { const configManager = ConfigManager.getInstance(); const aiConfig = await configManager.loadAiConfig(); if (aiConfig && Object.keys(aiConfig).length > 1) { // More than just metadata console.log(`📄 Loading AI config from: ${configManager.getAiConfigFilePath()}`); // Check Multi-AI Review configuration and log the mode const multiAiReviewEnabled = aiConfig.multi_ai_review_enabled || false; const primaryProvider = aiConfig.primary_review_provider_id || null; if (multiAiReviewEnabled) { console.log(`🔄 Multi-AI Review mode: All configured providers will be contacted`); } else if (primaryProvider) { console.log(`🎯 Single-AI Review mode: Only ${primaryProvider} will be contacted`); } else { console.log(`⚠️ No primary provider set - all providers will be contacted`); } // Convert from global AI config to AIReviewConfig format const reviewConfig = this.convertAiConfigToAIConfig(aiConfig); if (this.validateConfig(reviewConfig)) { this.config = reviewConfig; return this.config; } else { console.warn(`⚠️ Invalid AI config in global configuration`); } } console.log('🤖 No AI review configuration found. AI features disabled.'); console.log('💡 Run "woaru ai setup" to configure AI providers for code review.'); return null; } catch (error) { console.warn(`⚠️ Failed to load global AI config:`, error instanceof Error ? error.message : error); return null; } } /** * Get default configuration for testing */ getDefaultConfig() { return { providers: [ { id: 'anthropic-claude', providerType: 'anthropic', apiKeyEnvVar: 'ANTHROPIC_API_KEY', baseUrl: 'https://api.anthropic.com/v1/messages', model: 'claude-3-5-sonnet-20241022', headers: { 'anthropic-version': '2023-06-01', }, bodyTemplate: JSON.stringify({ model: '{model}', max_tokens: 4000, temperature: 0.1, messages: [ { role: 'user', content: '{prompt}\n\nCode to analyze:\n```{language}\n{code}\n```', }, ], }), timeout: 30000, maxTokens: 4000, temperature: 0.1, enabled: true, }, ], parallelRequests: true, consensusMode: false, minConsensusCount: 2, tokenLimit: 8000, costThreshold: 0.5, }; } /** * Convert global AI config to AIReviewConfig format * Respects Multi-AI Review configuration settings */ convertAiConfigToAIConfig(aiConfig) { const providers = []; // Check Multi-AI Review configuration const multiAiReviewEnabled = aiConfig.multi_ai_review_enabled || false; const primaryProvider = aiConfig.primary_review_provider_id || null; // Validate Single-AI Review mode configuration if (!multiAiReviewEnabled && primaryProvider) { const availableProviders = Object.keys(aiConfig).filter(key => ![ '_metadata', 'multi_ai_review_enabled', 'primary_review_provider_id', 'multiAi', 'primaryProvider', 'lastDataUpdate', ].includes(key) && !key.startsWith('_') // Exclude any metadata keys ); if (!availableProviders.includes(primaryProvider)) { console.warn(`⚠️ Primary provider '${primaryProvider}' not found in configuration. Available providers: ${availableProviders.join(', ')}`); console.log(`🔄 Falling back to Multi-AI Review mode`); } } // Convert each configured AI provider to AI review format for (const [providerId, providerConfig] of Object.entries(aiConfig)) { if (providerId === '_metadata' || providerId === 'multi_ai_review_enabled' || providerId === 'primary_review_provider_id' || providerId === 'multiAi' || providerId === 'primaryProvider' || providerId === 'lastDataUpdate' || providerId.startsWith('_') // Any key starting with underscore is metadata ) continue; const config = providerConfig; // Determine if this provider should be enabled based on Multi-AI Review settings let shouldEnable = config.enabled !== false; if (!multiAiReviewEnabled && primaryProvider) { // Single-AI Review mode: only enable the primary provider shouldEnable = shouldEnable && providerId === primaryProvider; } else if (!multiAiReviewEnabled && !primaryProvider) { // Single-AI Review mode but no primary provider set: enable all (fallback) // shouldEnable remains unchanged (all providers enabled in fallback) } // In Multi-AI Review mode: enable all configured providers (default behavior) providers.push({ id: providerId, providerType: (config.providerType || 'openai'), apiKeyEnvVar: config.apiKeyEnvVar || `${providerId.toUpperCase()}_API_KEY`, baseUrl: config.baseUrl || 'https://api.openai.com/v1/chat/completions', model: config.model || 'gpt-4', headers: config.headers || {}, bodyTemplate: config.bodyTemplate || JSON.stringify({ model: '{model}', messages: [ { role: 'user', content: '{prompt}\n\nCode to analyze:\n```{language}\n{code}\n```', }, ], max_tokens: 4000, temperature: 0.1, }), timeout: config.timeout || 30000, maxTokens: config.maxTokens || 4000, temperature: config.temperature || 0.1, enabled: shouldEnable, }); } return { providers, parallelRequests: true, consensusMode: false, minConsensusCount: 2, tokenLimit: 8000, costThreshold: 0.5, }; } /** * Validate configuration structure */ validateConfig(config) { if (!config || typeof config !== 'object') { return false; } const configObj = config; if (!Array.isArray(configObj.providers)) { console.warn('Config validation failed: providers must be an array'); return false; } for (const provider of configObj.providers) { const providerObj = provider; if (!providerObj.id || !providerObj.providerType || !providerObj.baseUrl || !providerObj.model) { console.warn('Config validation failed: provider missing required fields', provider); return false; } } return true; } /** * Check if AI features are available */ async isAIAvailable(_projectPath) { const config = await this.loadConfig(_projectPath); return config !== null && config.providers.some(p => p.enabled); } /** * Get enabled providers */ async getEnabledProviders(_projectPath) { const config = await this.loadConfig(_projectPath); return config?.providers.filter(p => p.enabled).map(p => p.id) || []; } /** * Get Multi-AI Review configuration status */ async getMultiAiReviewConfig() { try { const configManager = ConfigManager.getInstance(); const aiConfig = await configManager.loadAiConfig(); const multiAiReviewEnabled = aiConfig.multi_ai_review_enabled || false; const primaryProvider = aiConfig.primary_review_provider_id || null; let mode = 'Multi-AI Review'; if (!multiAiReviewEnabled && primaryProvider) { mode = `Single-AI Review (${primaryProvider})`; } else if (!multiAiReviewEnabled && !primaryProvider) { mode = 'Multi-AI Review (fallback)'; } return { enabled: Boolean(multiAiReviewEnabled), primaryProvider: primaryProvider || null, mode, }; } catch { return { enabled: false, primaryProvider: null, mode: 'Not configured', }; } } /** * Reset cached configuration (for testing) */ resetConfig() { this.config = null; } } //# sourceMappingURL=ConfigLoader.js.map