@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
457 lines • 18.2 kB
JavaScript
/**
* OpenRouter Mastery Service
*
* Complete implementation of ALL OpenRouter API features and capabilities:
* - Routing variants (:nitro, :floor, :online, :free)
* - Streaming responses with real-time progress
* - JSON mode with schema validation
* - Function calling integration
* - Cost tracking and budget enforcement
* - Intelligent fallback systems
* - Provider performance monitoring
* - Advanced error handling and recovery
*/
import { getDatabase, getOpenRouterApiKey } from '../storage/unified-database.js';
// ===== ROUTING VARIANTS DEFINITIONS =====
export const ROUTING_VARIANTS = {
':nitro': {
variant: ':nitro',
description: 'Fastest available providers with premium performance',
costMultiplier: 1.2,
speedMultiplier: 2.0,
features: ['fastest_routing', 'premium_providers', 'low_latency']
},
':floor': {
variant: ':floor',
description: 'Most cost-effective options with good quality',
costMultiplier: 0.7,
speedMultiplier: 0.8,
features: ['cost_optimization', 'budget_friendly', 'efficient']
},
':online': {
variant: ':online',
description: 'Web-search augmented responses with current information',
costMultiplier: 1.1,
speedMultiplier: 0.9,
features: ['web_search', 'current_information', 'fact_checking']
},
':free': {
variant: ':free',
description: 'Rate-limited free access for development and testing',
costMultiplier: 0.0,
speedMultiplier: 0.6,
features: ['free_tier', 'rate_limited', 'development']
},
':default': {
variant: ':default',
description: 'Standard routing with balanced performance and cost',
costMultiplier: 1.0,
speedMultiplier: 1.0,
features: ['balanced', 'standard', 'reliable']
}
};
// ===== OPENROUTER MASTERY CLASS =====
export class OpenRouterMastery {
apiKey;
baseUrl = 'https://openrouter.ai/api/v1';
performanceCache = new Map();
circuitBreaker = new Map();
constructor(apiKey) {
this.apiKey = apiKey;
}
/**
* Master function that calls OpenRouter with ALL advanced features
*/
async callWithMastery(model, messages, options = {}) {
const startTime = Date.now();
let currentCost = 0;
let fallbacksUsed = 0;
let providerSwitches = 0;
const featuresUsed = [];
try {
// 1. Apply routing variant
const routedModel = this.applyRoutingVariant(model, options.routingVariant);
featuresUsed.push(`routing_${options.routingVariant || 'default'}`);
// 2. Check budget controls
if (options.budgetControls) {
await this.enforcebudgetControls(options.budgetControls, currentCost);
featuresUsed.push('budget_controls');
}
// 3. Check circuit breaker
if (this.isCircuitBreakerOpen(routedModel)) {
throw new Error(`Circuit breaker open for model: ${routedModel}`);
}
// 4. Prepare request with advanced features
const requestBody = await this.prepareAdvancedRequest(routedModel, messages, options, featuresUsed);
// 5. Execute request with streaming or standard call
let response;
if (options.streaming) {
response = await this.executeStreamingCall(requestBody, options, startTime);
featuresUsed.push('streaming');
}
else {
response = await this.executeStandardCall(requestBody, startTime);
}
// 6. Update performance metrics
await this.updatePerformanceMetrics(routedModel, response.performance);
// 7. Track feature usage
await this.trackFeatureUsage(routedModel, featuresUsed, response);
// 8. Prepare final response
response.metadata = {
routingVariant: options.routingVariant || ':default',
fallbacksUsed,
providerSwitches,
features: featuresUsed
};
return response;
}
catch (error) {
// Handle errors with intelligent fallback
return await this.handleErrorWithFallback(model, messages, options, error, startTime, { currentCost, fallbacksUsed, providerSwitches, featuresUsed });
}
}
/**
* Apply OpenRouter routing variants to model IDs
*/
applyRoutingVariant(model, variant) {
if (!variant || variant === ':default') {
return model;
}
// Remove any existing variant first
const baseModel = model.replace(/(:(nitro|floor|online|free))$/, '');
return `${baseModel}${variant}`;
}
/**
* Enforce budget controls and cost optimization
*/
async enforcebudgetControls(budgetControls, currentCost) {
if (budgetControls.maxTotalCost && currentCost >= budgetControls.maxTotalCost) {
throw new Error(`Budget exceeded: ${currentCost} >= ${budgetControls.maxTotalCost}`);
}
if (budgetControls.costThreshold && currentCost >= budgetControls.costThreshold) {
// Auto-switch to cost-effective variants
console.log(`💰 Cost threshold reached, switching to cost-optimized routing`);
}
}
/**
* Prepare request with advanced OpenRouter features
*/
async prepareAdvancedRequest(model, messages, options, featuresUsed) {
const requestBody = {
model,
messages,
stream: options.streaming || false
};
// JSON mode with schema validation
if (options.jsonMode && options.jsonSchema) {
requestBody.response_format = {
type: 'json_schema',
json_schema: options.jsonSchema
};
featuresUsed.push('json_mode', 'schema_validation');
}
// Function calling / tools
if (options.functionCalling && options.tools) {
requestBody.tools = options.tools;
requestBody.tool_choice = 'auto';
featuresUsed.push('function_calling', 'tools');
}
// Add OpenRouter-specific headers
requestBody.extra_headers = {
'HTTP-Referer': 'https://hive.ai',
'X-Title': 'Hive.AI Dynamic Consensus'
};
return requestBody;
}
/**
* Execute streaming call with real-time progress
*/
async executeStreamingCall(requestBody, options, startTime) {
let content = '';
let inputTokens = 0;
let outputTokens = 0;
let cost = 0;
const response = await fetch(`${this.baseUrl}/chat/completions`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
...requestBody.extra_headers
},
body: JSON.stringify(requestBody)
});
if (!response.ok) {
throw new Error(`OpenRouter API error: ${response.status} ${response.statusText}`);
}
const reader = response.body?.getReader();
if (!reader) {
throw new Error('No stream reader available');
}
const decoder = new TextDecoder();
try {
while (true) {
const { done, value } = await reader.read();
if (done)
break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n').filter(line => line.trim());
for (const line of lines) {
if (line.startsWith('data: ')) {
const jsonStr = line.slice(6);
if (jsonStr === '[DONE]')
continue;
try {
const data = JSON.parse(jsonStr);
// Extract content
if (data.choices?.[0]?.delta?.content) {
const deltaContent = data.choices[0].delta.content;
content += deltaContent;
// Call progress callback
if (options.streamingOptions?.onProgress) {
options.streamingOptions.onProgress(deltaContent);
}
}
// Extract usage and cost information
if (data.usage) {
inputTokens = data.usage.prompt_tokens || inputTokens;
outputTokens = data.usage.completion_tokens || outputTokens;
if (options.streamingOptions?.onTokenCount) {
options.streamingOptions.onTokenCount(inputTokens, outputTokens);
}
}
}
catch (parseError) {
// Skip invalid JSON lines
continue;
}
}
}
}
}
finally {
reader.releaseLock();
}
const latencyMs = Date.now() - startTime;
return {
content,
model: requestBody.model,
provider: this.extractProvider(requestBody.model),
cost,
tokens: { input: inputTokens, output: outputTokens },
performance: { latencyMs, successRate: 1.0 },
metadata: { routingVariant: '', fallbacksUsed: 0, providerSwitches: 0, features: [] }
};
}
/**
* Execute standard (non-streaming) call
*/
async executeStandardCall(requestBody, startTime) {
const response = await fetch(`${this.baseUrl}/chat/completions`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
...requestBody.extra_headers
},
body: JSON.stringify(requestBody)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`OpenRouter API error: ${response.status} ${response.statusText} - ${errorText}`);
}
const data = await response.json();
const latencyMs = Date.now() - startTime;
return {
content: data.choices[0]?.message?.content || '',
model: data.model || requestBody.model,
provider: this.extractProvider(data.model || requestBody.model),
cost: this.calculateCost(data.usage),
tokens: {
input: data.usage?.prompt_tokens || 0,
output: data.usage?.completion_tokens || 0
},
performance: { latencyMs, successRate: 1.0 },
metadata: { routingVariant: '', fallbacksUsed: 0, providerSwitches: 0, features: [] }
};
}
/**
* Handle errors with intelligent fallback strategies
*/
async handleErrorWithFallback(originalModel, messages, options, error, startTime, context) {
console.warn(`⚠️ OpenRouter call failed: ${error.message}`);
// Update circuit breaker
this.updateCircuitBreaker(originalModel, false);
// Try fallback strategies
if (context.fallbacksUsed < 3) { // Max 3 fallbacks
// Strategy 1: Try different routing variant
if (options.routingVariant === ':nitro') {
console.log('🔄 Falling back from :nitro to :default variant');
const fallbackOptions = { ...options, routingVariant: ':default' };
context.fallbacksUsed++;
return await this.callWithMastery(originalModel, messages, fallbackOptions);
}
// Strategy 2: Try :floor variant for cost issues
if (error.message.includes('budget') || error.message.includes('cost')) {
console.log('🔄 Falling back to :floor variant for cost optimization');
const fallbackOptions = { ...options, routingVariant: ':floor' };
context.fallbacksUsed++;
return await this.callWithMastery(originalModel, messages, fallbackOptions);
}
// Strategy 3: Try :free variant as emergency fallback
if (options.budgetControls?.emergencyFallback) {
console.log('🔄 Emergency fallback to :free variant');
const fallbackOptions = { ...options, routingVariant: ':free' };
context.fallbacksUsed++;
return await this.callWithMastery(originalModel, messages, fallbackOptions);
}
}
// If all fallbacks failed, throw the original error
throw error;
}
/**
* Circuit breaker pattern for provider health management
*/
isCircuitBreakerOpen(model) {
const breaker = this.circuitBreaker.get(model);
if (!breaker)
return false;
const now = Date.now();
const timeSinceLastFailure = now - breaker.lastFailure;
// Reset circuit breaker after 5 minutes
if (timeSinceLastFailure > 5 * 60 * 1000) {
breaker.isOpen = false;
breaker.failures = 0;
}
return breaker.isOpen;
}
updateCircuitBreaker(model, success) {
let breaker = this.circuitBreaker.get(model);
if (!breaker) {
breaker = { failures: 0, lastFailure: 0, isOpen: false };
this.circuitBreaker.set(model, breaker);
}
if (success) {
breaker.failures = 0;
breaker.isOpen = false;
}
else {
breaker.failures++;
breaker.lastFailure = Date.now();
// Open circuit breaker after 3 consecutive failures
if (breaker.failures >= 3) {
breaker.isOpen = true;
console.warn(`🚨 Circuit breaker opened for model: ${model}`);
}
}
}
/**
* Update provider performance metrics
*/
async updatePerformanceMetrics(model, performance) {
const db = await getDatabase();
const modelInternalId = await this.getModelInternalId(model);
if (modelInternalId) {
try {
await db.run(`
INSERT OR REPLACE INTO provider_performance
(model_internal_id, provider_name, routing_variant, avg_latency_ms, success_rate, measured_at)
VALUES (?, ?, ?, ?, ?, ?)
`, [
modelInternalId,
this.extractProvider(model),
this.extractVariant(model),
performance.latencyMs,
performance.successRate,
new Date().toISOString()
]);
}
catch (error) {
console.warn('Failed to update performance metrics:', error);
}
}
}
/**
* Track feature usage for analytics
*/
async trackFeatureUsage(model, features, response) {
// This will be called with conversation_id when integrated with consensus engine
console.log(`📊 Features used: ${features.join(', ')} for model: ${model}`);
}
// ===== UTILITY FUNCTIONS =====
extractProvider(model) {
return model.split('/')[0] || 'unknown';
}
extractVariant(model) {
const match = model.match(/(:(nitro|floor|online|free))$/);
return match ? match[1] : ':default';
}
calculateCost(usage) {
// Simplified cost calculation - in real implementation would use model-specific pricing
if (!usage)
return 0;
const inputCost = (usage.prompt_tokens || 0) * 0.000001; // $1 per 1M tokens
const outputCost = (usage.completion_tokens || 0) * 0.000002; // $2 per 1M tokens
return inputCost + outputCost;
}
async getModelInternalId(openrouterId) {
try {
const db = await getDatabase();
const result = await db.get('SELECT internal_id FROM openrouter_models WHERE openrouter_id = ?', [openrouterId.replace(/(:(nitro|floor|online|free))$/, '')] // Remove variant for lookup
);
return result?.internal_id || null;
}
catch (error) {
console.warn('Failed to get model internal ID:', error);
return null;
}
}
}
// ===== CONVENIENCE FUNCTIONS =====
/**
* Create OpenRouter mastery instance
*/
export async function createOpenRouterMastery() {
const apiKey = await getOpenRouterApiKey();
if (!apiKey) {
throw new Error('OpenRouter API key not configured');
}
return new OpenRouterMastery(apiKey);
}
/**
* Quick call with routing variant
*/
export async function callWithVariant(model, messages, variant) {
const mastery = await createOpenRouterMastery();
return await mastery.callWithMastery(model, messages, { routingVariant: variant });
}
/**
* Quick streaming call
*/
export async function callWithStreaming(model, messages, onProgress) {
const mastery = await createOpenRouterMastery();
return await mastery.callWithMastery(model, messages, {
streaming: true,
streamingOptions: { onProgress }
});
}
/**
* Budget-controlled call
*/
export async function callWithBudget(model, messages, maxCost) {
const mastery = await createOpenRouterMastery();
return await mastery.callWithMastery(model, messages, {
budgetControls: { maxCostPerCall: maxCost }
});
}
/**
* JSON mode call with schema
*/
export async function callWithJsonSchema(model, messages, schema) {
const mastery = await createOpenRouterMastery();
return await mastery.callWithMastery(model, messages, {
jsonMode: true,
jsonSchema: schema
});
}
export default OpenRouterMastery;
//# sourceMappingURL=openrouter-mastery.js.map