UNPKG

behemoth-cli

Version:

🌍 BEHEMOTH CLIv3.760.4 - Level 50+ POST-SINGULARITY Intelligence Trading AI

249 lines (206 loc) 6.26 kB
import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; interface Config { groqApiKey?: string; groqApiKeys?: string[]; // Array of API keys for rotation currentKeyIndex?: number; // Current key being used defaultModel?: string; n8nUrl?: string; n8nApiKey?: string; } const CONFIG_DIR = '.groq'; // In home directory const CONFIG_FILE = 'local-settings.json'; export class ConfigManager { private configPath: string; constructor() { const homeDir = os.homedir(); this.configPath = path.join(homeDir, CONFIG_DIR, CONFIG_FILE); } private ensureConfigDir(): void { const configDir = path.dirname(this.configPath); if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, {recursive: true, mode: 0o700}); } } public setApiKey(apiKey: string): void { try { this.ensureConfigDir(); let config: Config = {}; if (fs.existsSync(this.configPath)) { const configData = fs.readFileSync(this.configPath, 'utf8'); config = JSON.parse(configData); } config.groqApiKey = apiKey; fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600, // Read/write for owner only }); } catch (error) { throw new Error(`Failed to save API key: ${error}`); } } public addApiKey(apiKey: string): void { try { this.ensureConfigDir(); let config: Config = {}; if (fs.existsSync(this.configPath)) { const configData = fs.readFileSync(this.configPath, 'utf8'); config = JSON.parse(configData); } if (!config.groqApiKeys) { config.groqApiKeys = []; } if (!config.groqApiKeys.includes(apiKey)) { config.groqApiKeys.push(apiKey); } fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600, // Read/write for owner only }); } catch (error) { throw new Error(`Failed to add API key: ${error}`); } } public getApiKey(): string | null { try { if (!fs.existsSync(this.configPath)) { return null; } const configData = fs.readFileSync(this.configPath, 'utf8'); const config: Config = JSON.parse(configData); return config.groqApiKey || null; } catch (error) { console.warn('Failed to read API key:', error); return null; } } public getApiKeys(): string[] { try { if (!fs.existsSync(this.configPath)) { return []; } const configData = fs.readFileSync(this.configPath, 'utf8'); const config: Config = JSON.parse(configData); return config.groqApiKeys || []; } catch (error) { console.warn('Failed to read API keys:', error); return []; } } public setCurrentKeyIndex(index: number): void { try { this.ensureConfigDir(); let config: Config = {}; if (fs.existsSync(this.configPath)) { const configData = fs.readFileSync(this.configPath, 'utf8'); config = JSON.parse(configData); } config.currentKeyIndex = index; fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600, // Read/write for owner only }); } catch (error) { throw new Error(`Failed to save current key index: ${error}`); } } public getCurrentKeyIndex(): number | null { try { if (!fs.existsSync(this.configPath)) { return null; } const configData = fs.readFileSync(this.configPath, 'utf8'); const config: Config = JSON.parse(configData); return config.currentKeyIndex ?? null; } catch (error) { console.warn('Failed to read current key index:', error); return null; } } public getDefaultModel(): string | null { try { if (!fs.existsSync(this.configPath)) { return null; } const configData = fs.readFileSync(this.configPath, 'utf8'); const config: Config = JSON.parse(configData); return config.defaultModel || null; } catch (error) { console.warn('Failed to read default model:', error); return null; } } public setN8nConfig(url: string, apiKey: string): void { try { this.ensureConfigDir(); let config: Config = {}; if (fs.existsSync(this.configPath)) { const configData = fs.readFileSync(this.configPath, 'utf8'); config = JSON.parse(configData); } config.n8nUrl = url; config.n8nApiKey = apiKey; fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600, }); } catch (error) { throw new Error(`Failed to save n8n config: ${error}`); } } public getN8nConfig(): {url: string; apiKey: string} | null { try { if (!fs.existsSync(this.configPath)) { return null; } const configData = fs.readFileSync(this.configPath, 'utf8'); const config: Config = JSON.parse(configData); if (config.n8nUrl && config.n8nApiKey) { return {url: config.n8nUrl, apiKey: config.n8nApiKey}; } return null; } catch (error) { console.warn('Failed to read n8n config:', error); return null; } } public setDefaultModel(model: string): void { try { this.ensureConfigDir(); let config: Config = {}; if (fs.existsSync(this.configPath)) { const configData = fs.readFileSync(this.configPath, 'utf8'); config = JSON.parse(configData); } config.defaultModel = model; fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600 // Read/write for owner only }); } catch (error) { throw new Error(`Failed to save default model: ${error}`); } } public getCurrentApiKey(): string | null { try { const keys = this.getApiKeys(); const currentIndex = this.getCurrentKeyIndex() || 0; if (keys.length === 0) { return this.getApiKey(); // Fallback to single key } return keys[currentIndex % keys.length] || null; } catch (error) { console.warn('Failed to get current API key:', error); return null; } } public rotateApiKey(): void { try { const keys = this.getApiKeys(); if (keys.length <= 1) { return; // No rotation needed for single key or no keys } const currentIndex = this.getCurrentKeyIndex() || 0; const nextIndex = (currentIndex + 1) % keys.length; this.setCurrentKeyIndex(nextIndex); } catch (error) { console.warn('Failed to rotate API key:', error); } } }