UNPKG

@hivetechs/hive-ai

Version:

Real-time streaming AI consensus platform with HTTP+SSE MCP integration for Claude Code, VS Code, Cursor, and Windsurf - powered by OpenRouter's unified API

293 lines โ€ข 11.4 kB
/** * OpenRouter-Exclusive Provider Configuration * * Simplified configuration system that only supports OpenRouter. * No more managing 55+ provider integrations - OpenRouter handles everything. * * Architecture Decision (June 2025): * After extensive research, we've determined that maintaining individual * provider integrations is unsustainable and unnecessary when OpenRouter * provides unified access to all providers through one API. */ import { z } from "zod"; import { defaultValidator, SecurityValidationError } from '../../security/input-validator.js'; import { createChatCompletion, isOpenRouterConfigured, getSetupInstructions } from './provider-client.js'; // Removed openRouterSyncManager - now using direct database access import { saveOpenRouterApiKey, getOpenRouterApiKey, validateOpenRouterApiKey } from '../../storage/unified-database.js'; /** * Configure OpenRouter - the ONLY provider we support */ async function configureOpenRouter(api_key) { const now = new Date().toISOString(); try { // Validate the API key format const validatedApiKey = defaultValidator.validateApiKey(api_key); // Warn if it doesn't look like an OpenRouter key if (!validatedApiKey.startsWith('sk-or-')) { console.warn('โš ๏ธ This doesn\'t look like an OpenRouter API key (should start with sk-or-)'); console.warn(' Make sure you\'re using your OpenRouter key from https://openrouter.ai/keys'); } // Test if the API key actually works console.log('๐Ÿ” Testing API key authentication...'); const { testOpenRouterApiKeyAuthentication } = await import('../../storage/unified-database.js'); const authTest = await testOpenRouterApiKeyAuthentication(validatedApiKey); if (!authTest.valid) { throw new Error(`API key authentication failed: ${authTest.error}`); } // Store in unified database (single source of truth) await saveOpenRouterApiKey(validatedApiKey); console.log('โœ… OpenRouter configured successfully!'); console.log('๐Ÿ” API key authentication verified'); console.log('๐ŸŒ You now have access to 300+ models from 55+ providers'); console.log(''); console.log('Test your setup with:'); console.log(' hive test-providers'); console.log(''); console.log('Start using consensus AI:'); console.log(' hive consensus "Your question here"'); // Return simple configuration return { api_key: validatedApiKey, configured_at: now }; } catch (error) { if (error instanceof SecurityValidationError) { throw new Error(`Invalid API key format: ${error.message}`); } throw error; } } /** * Check if OpenRouter is configured */ async function isOpenRouterReady() { try { const apiKey = await getOpenRouterApiKey(); return !!apiKey && validateOpenRouterApiKey(apiKey); } catch (error) { return false; } } /** * Test OpenRouter connectivity with a simple request */ async function testOpenRouter() { try { const isConfigured = await isOpenRouterReady(); if (!isConfigured) { return { success: false, message: 'No OpenRouter configuration found. Please configure OpenRouter first.' }; } // Get a test model from OpenRouter data - no hardcoded fallbacks let testModel = null; try { const { getDatabase } = await import('../../storage/unified-database.js'); const database = await getDatabase(); // Find a free model for testing if available const freeModel = await database.get(` SELECT openrouter_id FROM openrouter_models WHERE is_active = 1 AND pricing_input = 0 AND pricing_output = 0 LIMIT 1 `); if (freeModel) { testModel = freeModel.openrouter_id; } else { // Use any available model const anyModel = await database.get(` SELECT openrouter_id FROM openrouter_models WHERE is_active = 1 LIMIT 1 `); if (anyModel) { testModel = anyModel.openrouter_id; } } } catch (error) { console.warn('Failed to get models from database for testing:', error); } if (!testModel) { return { success: false, message: 'No OpenRouter models available for testing. Try: hive models update' }; } // Test with a minimal request const result = await createChatCompletion({ model: testModel, messages: [{ role: 'user', content: 'Hi' }], max_tokens: 10 }); if (result?.content) { return { success: true, message: `Connected successfully using ${testModel}` }; } else { return { success: false, message: 'Empty response from OpenRouter' }; } } catch (error) { // Parse common OpenRouter errors const message = error.message || 'Unknown error'; if (message.includes('401') || message.includes('Invalid OpenRouter API key')) { return { success: false, message: 'Invalid API key - please check your OpenRouter key' }; } else if (message.includes('402') || message.includes('insufficient credits')) { return { success: false, message: 'Insufficient credits - please add credits at https://openrouter.ai/credits' }; } else if (message.includes('429')) { return { success: false, message: 'Rate limited - please wait and try again' }; } return { success: false, message: `Connection error: ${message}` }; } } // Tool exports export const configureProviderToolName = 'configure_provider'; export const configureProviderToolDescription = 'Configure OpenRouter API key for unified access to 300+ AI models'; export const listProvidersToolName = 'list_providers'; export const listProvidersToolDescription = 'Show OpenRouter configuration and available models'; export const testProvidersToolName = 'test_providers'; export const testProvidersToolDescription = 'Test OpenRouter connectivity'; // Tool schemas export const ConfigureProviderToolSchema = z.object({ command: z.string().describe('Command: "openrouter YOUR_API_KEY"') }); export const ListProvidersToolSchema = z.object({}); export const TestProvidersToolSchema = z.object({}); // Tool handlers export async function runConfigureProviderTool(args) { const { command } = args; const parts = command.trim().split(/\s+/); if (parts.length < 2) { return { result: getSetupInstructions() }; } const [providerName, apiKey] = parts; // Only accept OpenRouter configuration if (providerName.toLowerCase() !== 'openrouter') { return { result: `โŒ Only OpenRouter is supported.\n\n${getSetupInstructions()}` }; } try { await configureOpenRouter(apiKey); // Mask the API key for display const maskedKey = apiKey.substring(0, 8) + '...' + apiKey.substring(apiKey.length - 4); return { result: `โœ… OpenRouter configured successfully!\n\n` + `**API Key**: ${maskedKey}\n` + `**Access**: 300+ models from 55+ providers\n\n` + `**Next steps:**\n` + `โ€ข Test: \`hive-ai test-providers\`\n` + `โ€ข Use: \`hive-ai consensus "your question"\`` }; } catch (error) { return { result: `โŒ Configuration failed: ${error.message}\n\n${getSetupInstructions()}` }; } } export async function runListProvidersTool() { try { const apiKey = await getOpenRouterApiKey(); if (!apiKey) { return { result: `โŒ OpenRouter not configured\n\n${getSetupInstructions()}` }; } const maskedKey = apiKey.substring(0, 8) + '...' + apiKey.substring(apiKey.length - 4); return { result: `# OpenRouter Configuration\n\n` + `โœ… **Status**: Active\n` + `๐Ÿ”‘ **API Key**: ${maskedKey}\n` + `๐ŸŒ **Access**: 300+ models from 55+ providers\n\n` + `**Available through OpenRouter:**\n` + `โ€ข OpenAI (GPT-4, GPT-3.5, etc.)\n` + `โ€ข Anthropic (Claude 3.5, Claude 3, etc.)\n` + `โ€ข Google (Gemini Pro, PaLM, etc.)\n` + `โ€ข Meta (Llama models)\n` + `โ€ข And 50+ more providers\n\n` + `**Test**: \`hive test-providers\`\n` + `**Use**: \`hive consensus "your question"\`` }; } catch (error) { return { result: `โŒ Error checking configuration: ${error.message}` }; } } export async function runTestProvidersTool() { try { const configured = await isOpenRouterConfigured(); if (!configured) { return { result: `โŒ OpenRouter not configured\n\n${getSetupInstructions()}` }; } console.log('๐Ÿงช Testing OpenRouter connectivity...'); const result = await testOpenRouter(); if (result.success) { return { result: `## ๐Ÿงช OpenRouter Test Results\n\n` + `โœ… **Status**: Connected\n` + `๐ŸŒ **Access**: All 300+ models available\n` + `๐Ÿ’ก **Details**: ${result.message}\n\n` + `**Ready to use!**\n` + `Try: \`hive consensus "Design a scalable system"\`` }; } else { // Provide helpful error resolution let helpText = ''; if (result.message.includes('Invalid API key')) { helpText = `\n**Fix**: Update your API key\n\`hive provider configure openrouter <new-key>\`\n\nGet a new key: https://openrouter.ai/keys`; } else if (result.message.includes('Insufficient credits')) { helpText = `\n**Fix**: Add credits to your OpenRouter account\nhttps://openrouter.ai/credits`; } return { result: `## ๐Ÿงช OpenRouter Test Results\n\n` + `โŒ **Status**: ${result.message}\n` + `${helpText}\n\n` + `**Need help?** Visit https://openrouter.ai/docs` }; } } catch (error) { return { result: `โŒ Test failed: ${error.message}\n\n๐Ÿ’ก Try reconfiguring:\n\`hive provider configure openrouter <your-key>\`` }; } } // Simple OpenRouter utilities export const providerUtils = { configureOpenRouter, testOpenRouter, isConfigured: isOpenRouterConfigured }; //# sourceMappingURL=provider-config.js.map