UNPKG

tryaii-mcp-server

Version:

TryAII MCP Server - 15+ AI models with comparison, cost tracking, and collective intelligence

164 lines 6.71 kB
/** * Centralized cost calculation utility to ensure consistency * between McpProtocolHandler balance deduction and SessionManager database storage */ import { logger } from './logger.js'; /** * Calculate actual total cost from tool execution result * This is the authoritative cost calculation used by both: * - McpProtocolHandler (for balance deduction) * - SessionManager (for database session cost) */ export function calculateActualCost(result, toolName) { const defaultResult = { totalCost: 0, modelCount: 0, successfulModels: 0, breakdown: [] }; try { // Parse the result to extract actual model costs if (!result || !result.content || !result.content[0] || !result.content[0].text) { logger.warn('No result content to extract cost from - using fallback pricing', { toolName }); return getFallbackCost(toolName); } const resultData = JSON.parse(result.content[0].text); // Handle brains response format - sum costs from 5 AI models if (toolName === 'brains' && resultData.responses && Array.isArray(resultData.responses)) { let totalCost = 0; const breakdown = []; let successfulModels = 0; for (const response of resultData.responses) { const modelCost = response.cost || 0; const modelId = response.model?.id || response.modelId || 'unknown'; const success = response.status === 'success'; totalCost += modelCost; if (success) successfulModels++; breakdown.push({ modelId, cost: modelCost, success }); } // If no cost data found, use fallback if (totalCost === 0) { logger.warn('Brains response has no cost data - using fallback', { responseCount: resultData.responses.length }); return getFallbackCost(toolName); } const result = { totalCost, modelCount: resultData.responses.length, successfulModels, breakdown }; logger.info('Calculated actual cost from brains result', { toolName, ...result }); return result; } // Handle compare_models response format - sum costs from multiple models else if (toolName === 'compare_models' && resultData.results && Array.isArray(resultData.results)) { let totalCost = 0; const breakdown = []; let successfulModels = 0; for (const modelResult of resultData.results) { const modelCost = modelResult.cost || 0; const modelId = modelResult.modelId || 'unknown'; const success = modelResult.success !== false; totalCost += modelCost; if (success) successfulModels++; breakdown.push({ modelId, cost: modelCost, success }); } // If no cost data found, use fallback if (totalCost === 0) { logger.warn('Compare response has no cost data - using fallback', { modelCount: resultData.results.length }); return getFallbackCost(toolName, resultData.results.length); } const result = { totalCost, modelCount: resultData.results.length, successfulModels, breakdown }; logger.info('Calculated actual cost from compare result', { toolName, ...result }); return result; } // Handle chat_with_model response format - single model cost else if (toolName === 'chat_with_model' && resultData.cost !== undefined) { const cost = resultData.cost || 0; // If no cost data found, use fallback if (cost === 0) { logger.warn('Chat response has no cost data - using fallback'); return getFallbackCost(toolName); } const result = { totalCost: cost, modelCount: 1, successfulModels: 1, breakdown: [{ modelId: resultData.modelId || 'unknown', cost, success: true }] }; logger.info('Calculated actual cost from chat result', { toolName, ...result }); return result; } // If we have response data but no recognizable cost format, use intelligent fallback logger.warn('Response format not recognized - using intelligent fallback', { toolName, hasResponses: !!resultData.responses, hasResults: !!resultData.results, hasCost: !!resultData.cost }); return getFallbackCost(toolName); } catch (parseError) { logger.error('Failed to parse result for cost extraction - using fallback', { toolName, error: parseError instanceof Error ? parseError.message : parseError }); return getFallbackCost(toolName); } } /** * Get fallback cost when actual cost cannot be determined * Uses conservative pricing to ensure minimum revenue */ function getFallbackCost(toolName, modelCount) { const fallbackCosts = { 'brains': 0.15, // 5 top models - increased from 0.10 'compare_models': 0.08, // Variable based on model count - increased from 0.06 'chat_with_model': 0.03, // Single model - increased from 0.02 'list_available_models': 0, // Free 'get_model_info': 0 // Free }; let baseCost = fallbackCosts[toolName] || 0.02; // Default fallback cost // Adjust costs based on parameters if (toolName === 'compare_models' && modelCount) { baseCost = Math.min(modelCount * 0.025, 0.25); // Cap at $0.25, increased rate } const result = { totalCost: baseCost, modelCount: toolName === 'brains' ? 5 : (modelCount || 1), successfulModels: toolName === 'brains' ? 5 : (modelCount || 1), breakdown: [{ modelId: 'fallback', cost: baseCost, success: true }] }; logger.warn('Using fallback cost calculation', { toolName, ...result }); return result; } //# sourceMappingURL=costCalculator.js.map