@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
JavaScript
/**
* 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