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

308 lines • 14.2 kB
import { z } from "zod"; import { providerUtils } from './provider-config.js'; import * as readline from 'readline'; // Schema for the list models tool export const ListModelsToolSchema = z.object({ provider_name: z.string().optional().describe('Optional provider name to filter models (e.g., openai, anthropic, google)') }); // Schema for the update models tool export const UpdateModelsToolSchema = z.object({}); // Schema for the add model tool (now deprecated in favor of OpenRouter auto-discovery) export const AddModelToolSchema = z.object({ provider_name: z.string().describe('Provider name'), model_id: z.string().describe('Model ID'), capability: z.string().describe('Capability (e.g., chat, embedding, image)'), description: z.string().optional().describe('Optional description'), context_window: z.number().optional().describe('Optional context window size') }); /** * Run the list models tool */ export async function runListModelsTool(args) { try { const { provider_name } = args || {}; // Check if OpenRouter is configured first const isConfigured = await providerUtils.isConfigured(); if (!isConfigured) { return { result: "āŒ OpenRouter not configured\n\n" + "Configure OpenRouter to access all models:\n" + "`hive provider configure openrouter <your-api-key>`\n\n" + "Get your API key: https://openrouter.ai/keys" }; } // Get models directly from our bulletproof database const { getDatabase } = await import('../../storage/unified-database.js'); const database = await getDatabase(); if (!provider_name) { // List all providers with their models const providers = await database.all(` SELECT DISTINCT provider_name, COUNT(*) as model_count FROM openrouter_models WHERE is_active = 1 GROUP BY provider_name ORDER BY provider_name `); if (providers.length === 0) { return { result: "āŒ No models found. Please run:\n\n" + "`hive models update` to sync model data" }; } let result = "# 🌐 Available Models Through OpenRouter\n\n"; result += `āœ… **${providers.length} providers** with bulletproof model database\n\n`; for (const provider of providers.slice(0, 10)) { // Show first 10 providers result += `## ${provider.provider_name}\n`; try { const models = await database.all(` SELECT * FROM openrouter_models WHERE provider_name = ? AND is_active = 1 ORDER BY name LIMIT 3 `, [provider.provider_name]); result += `**${provider.model_count} models** available\n`; // Show first few models as examples for (const model of models) { result += `• **${model.openrouter_id}**`; if (model.context_window) { result += ` (${model.context_window.toLocaleString()} tokens)`; } result += `\n`; } if (provider.model_count > 3) { result += `• ... and ${provider.model_count - 3} more models\n`; } } catch (error) { result += "Error loading models\n"; } result += "\n"; } if (providers.length > 10) { result += `... and ${providers.length - 10} more providers\n\n`; } result += "**Commands:**\n"; result += "• List specific provider: `hive models list <provider-name>`\n"; result += "• Setup profiles: `hive setup`\n"; result += "• Use consensus: `hive consensus \"your question\"`"; return { result }; } // Provider-specific listing const providerModels = await database.all(` SELECT * FROM openrouter_models WHERE provider_name = ? AND is_active = 1 ORDER BY name `, [provider_name]); if (providerModels.length === 0) { const availableProviders = await database.all(` SELECT DISTINCT provider_name FROM openrouter_models WHERE is_active = 1 `); return { result: `āŒ Provider "${provider_name}" not found.\n\n` + `Available providers: ${availableProviders.map(p => p.provider_name).join(', ')}\n\n` + "Use: `hive models list` to see all providers" }; } let result = `# šŸ¤– Available Models for ${provider_name}\n\n`; result += `**${providerModels.length} models** available through OpenRouter\n\n`; // Show all models for (let i = 0; i < providerModels.length; i++) { const model = providerModels[i]; result += `${i + 1}. **${model.openrouter_id}**`; if (model.context_window) { result += ` (${model.context_window.toLocaleString()} tokens)`; } if (model.description) { result += `: ${model.description}`; } result += "\n"; } // Get API key for display const apiKey = await import('../../storage/unified-database.js').then(db => db.getOpenRouterApiKey()); const keyDisplay = apiKey ? `...${apiKey.slice(-4)}` : 'configured'; result += `\nāœ… OpenRouter configured with API key ending in ${keyDisplay}\n`; result += `\n**Use these models in:**\n`; result += "• Pipeline profiles: `hive setup`\n"; result += "• Direct consensus: `hive consensus \"your question\"`"; return { result }; } catch (error) { return { result: `āŒ Error listing models: ${error.message || 'Unknown error'}\n\n` + "Try: `hive setup` to refresh provider data" }; } } /** * Run the update models tool - now updates OpenRouter data */ export async function runUpdateModelsTool() { try { // Check if OpenRouter is configured const isConfigured = await providerUtils.isConfigured(); if (!isConfigured) { return { result: "āŒ OpenRouter not configured\n\n" + "Configure OpenRouter first:\n" + "`hive provider configure openrouter <your-api-key>`" }; } console.log('šŸ”„ Starting bulletproof OpenRouter sync...'); // Get OpenRouter API key for direct fetch const { getOpenRouterApiKey } = await import('../../storage/unified-database.js'); const apiKey = await getOpenRouterApiKey(); if (!apiKey) { throw new Error('OpenRouter API key not found'); } // Fetch models directly from OpenRouter API (bypassing old sync manager) console.log('šŸ“„ Fetching models directly from OpenRouter API...'); const response = await fetch('https://openrouter.ai/api/v1/models', { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); if (!response.ok) { throw new Error(`OpenRouter API error: ${response.status} ${response.statusText}`); } const apiData = await response.json(); const allModelsData = apiData.data || []; console.log(`šŸ“Š Fetched ${allModelsData.length} models from OpenRouter API`); console.log('šŸ”„ Processing and updating database...'); // Run our bulletproof migration sync (handles model ID changes!) const { syncOpenRouterModelsWithMigration, initializeUnifiedDatabase } = await import('../../storage/unified-database.js'); // Ensure database is properly initialized first await initializeUnifiedDatabase(); const changes = await syncOpenRouterModelsWithMigration(allModelsData); // Run template maintenance after model sync console.log('šŸ”§ Running template maintenance...'); try { const { runTemplateMaintenanceIfDue } = await import('./template-maintenance.js'); await runTemplateMaintenanceIfDue(); console.log('āœ… Template maintenance completed'); } catch (error) { console.warn('āš ļø Template maintenance failed (non-critical):', error); } // Count providers from the data const providers = [...new Set(allModelsData.map((m) => m.id.split('/')[0]))].length; let result = `āœ… Bulletproof OpenRouter sync completed!\n\n`; result += `**${providers} providers** with **${allModelsData.length} models** processed\n\n`; result += `**šŸŽÆ Bulletproof Migration Results:**\n`; result += `• āž• Added: ${changes.added} new models\n`; result += `• šŸ”„ Updated: ${changes.updated} existing models\n`; result += `• šŸ”„ ID Changed: ${changes.idChanged} model IDs updated (profiles preserved!)\n`; result += `• šŸ’¤ Deactivated: ${changes.deactivated} deprecated models\n\n`; result += `**āœ… All profile references remain stable through model changes**\n\n`; result += `Use: \`hive models list\` to see all available models`; return { result }; } catch (error) { return { result: `āŒ Error during bulletproof OpenRouter sync: ${error.message || 'Unknown error'}\n\n` + "This may be due to:\n" + "• Network connectivity issues\n" + "• Invalid OpenRouter API key\n" + "• OpenRouter API temporarily unavailable\n\n" + "Your existing profiles remain safe with stable model references." }; } } /** * Run the add model tool - OpenRouter handles all models dynamically */ export async function runAddModelTool(args) { return { result: "ā„¹ļø **Custom models are no longer needed**\n\n" + "OpenRouter automatically provides access to 300+ models from 55+ providers.\n" + "All models are discovered and updated automatically.\n\n" + "**Instead of adding models manually:**\n" + "• Use: `hive models list` to see all available models\n" + "• Use: `hive models update` to sync latest model data\n" + "• Create profiles: `hive setup`\n\n" + "**OpenRouter supports:**\n" + "• All major AI providers (OpenAI, Anthropic, Google, Meta, etc.)\n" + "• Automatic model discovery\n" + "• Real-time availability updates\n" + "• Unified API access" }; } /** * Interactive model selection for CLI using OpenRouter data */ export async function selectModelInteractive(providerName, capability = 'chat') { try { // Get models from unified database const { getDatabase } = await import('../../storage/unified-database.js'); const database = await getDatabase(); const models = await database.all(` SELECT * FROM openrouter_models WHERE provider_name = ? AND is_active = 1 ORDER BY name `, [providerName]); if (models.length === 0) { console.log(`No models found for provider ${providerName}.`); console.log('Try running: hive models update'); return null; } console.log(`\nSelect a model for ${providerName}:\n`); for (let i = 0; i < models.length; i++) { const model = models[i]; console.log(`${i + 1}. ${model.openrouter_id}${model.context_window ? ` (${model.context_window.toLocaleString()} tokens)` : ''}`); if (model.description) { console.log(` ${model.description}\n`); } else { console.log(''); } } console.log(`${models.length + 1}. Enter a custom model ID\n`); console.log('Please make your selection below:'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); return new Promise((resolve) => { rl.question('Enter your choice (number or custom model ID): ', (answer) => { rl.close(); // Check if the answer is a number const choice = parseInt(answer); if (!isNaN(choice) && choice >= 1 && choice <= models.length) { // Selected from the list resolve(models[choice - 1].openrouter_id); } else if (!isNaN(choice) && choice === models.length + 1) { // Custom model ID const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout }); rl2.question('Enter custom model ID: ', (customId) => { rl2.close(); resolve(customId.trim()); }); } else { // Treat as custom model ID resolve(answer.trim()); } }); }); } catch (error) { console.error('Error loading models:', error.message); return null; } } // Tool exports export const listModelsToolName = 'list_models'; export const listModelsToolDescription = 'List available models from OpenRouter providers'; export const updateModelsToolName = 'update_models'; export const updateModelsToolDescription = 'Update model data from OpenRouter'; export const addModelToolName = 'add_model'; export const addModelToolDescription = 'Add custom model (deprecated - OpenRouter handles all models)'; // Export the model selection utilities export const modelSelectionUtils = { selectModelInteractive }; //# sourceMappingURL=model-selection.js.map