{"version":3,"sources":["../../../src/models/routers/CostOptimizer.ts","../../../src/models/routers/PerformanceRouter.ts","../../../src/models/routers/BalancedRouter.ts","../../../src/models/routers/CapabilityRouter.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { IRouter, SelectionCriteria, SelectionResult } from '../../types/routing';\nimport { ModelCatalog } from '../ModelCatalog';\nimport { Logger } from '../../utils/logger';\nimport { Model } from '../../types/models';\n\nexport class CostOptimizer implements IRouter {\n  constructor(\n    private catalog: ModelCatalog,\n    private logger: Logger,\n  ) {}\n\n  getName(): string {\n    return 'cost';\n  }\n\n  async route(query: string, criteria: SelectionCriteria): Promise<SelectionResult> {\n    await Promise.resolve(); // Keep async for consistent interface\n    this.logger.debug('CostOptimizer: Finding cheapest model (prioritizing free)', { criteria });\n\n    // First, try to get free models\n    let candidates = this.catalog.getFreeModels();\n\n    // If no free models or criteria specified, get filtered models\n    if (candidates.length === 0 || Object.keys(criteria).length > 0) {\n      candidates = this.catalog.filterModels(criteria);\n    }\n\n    if (candidates.length === 0) {\n      throw new Error('No models match the specified criteria');\n    }\n\n    // Sort by total cost (input + output) - free models naturally come first\n    const sorted = candidates.sort((a, b) => {\n      const aCost = a.pricing.inputTokens + a.pricing.outputTokens;\n      const bCost = b.pricing.inputTokens + b.pricing.outputTokens;\n      return aCost - bCost;\n    });\n\n    const selected = sorted[0];\n    const isFree = selected.pricing.inputTokens === 0 && selected.pricing.outputTokens === 0;\n\n    const alternatives = sorted.slice(1, 4).map((m, idx) => {\n      const mIsFree = m.pricing.inputTokens === 0 && m.pricing.outputTokens === 0;\n      return {\n        modelId: m.id,\n        score: this.calculateCostScore(m),\n        reason: mIsFree\n          ? `Alternative ${idx + 1}: FREE`\n          : `Alternative ${idx + 1}: ${this.formatCost(m)}`,\n      };\n    });\n\n    const expectedCost = (selected.pricing.inputTokens + selected.pricing.outputTokens) / 2;\n\n    return {\n      modelId: selected.id,\n      model: selected,\n      provider: selected.provider,\n      expectedCost,\n      reason: isFree\n        ? `FREE model: ${selected.name}`\n        : `Cheapest option: ${this.formatCost(selected)}`,\n      alternatives,\n      confidence: 0.95,\n    };\n  }\n\n  private calculateCostScore(model: Model): number {\n    // Lower cost = higher score\n    const totalCost = model.pricing.inputTokens + model.pricing.outputTokens;\n    return 1 / (totalCost + 1);\n  }\n\n  private formatCost(model: Model): string {\n    const input = model.pricing.inputTokens.toFixed(2);\n    const output = model.pricing.outputTokens.toFixed(2);\n    return `$${input}/$${output} per 1M tokens`;\n  }\n}\n","import { IRouter, SelectionCriteria, SelectionResult } from '../../types/routing';\nimport { ModelCatalog } from '../ModelCatalog';\nimport { Logger } from '../../utils/logger';\nimport { Model } from '../../types/models';\n\nexport class PerformanceRouter implements IRouter {\n  private performanceMetrics: Map<string, number> = new Map();\n\n  constructor(\n    private catalog: ModelCatalog,\n    private logger: Logger,\n  ) {\n    this.initializeMetrics();\n  }\n\n  getName(): string {\n    return 'performance';\n  }\n\n  async route(query: string, criteria: SelectionCriteria): Promise<SelectionResult> {\n    await Promise.resolve(); // Keep async for consistent interface\n    this.logger.debug('PerformanceRouter: Finding fastest model', { criteria });\n\n    const candidates = this.catalog.filterModels(criteria);\n\n    if (candidates.length === 0) {\n      throw new Error('No models match the specified criteria');\n    }\n\n    // Sort by performance score\n    const sorted = candidates.sort((a, b) => {\n      const aScore = this.getPerformanceScore(a);\n      const bScore = this.getPerformanceScore(b);\n      return bScore - aScore; // Higher is better\n    });\n\n    const selected = sorted[0];\n    const alternatives = sorted.slice(1, 4).map((m, idx) => ({\n      modelId: m.id,\n      score: this.getPerformanceScore(m),\n      reason: `Alternative ${idx + 1}: estimated ${this.getLatency(m)}ms latency`,\n    }));\n\n    const expectedCost = (selected.pricing.inputTokens + selected.pricing.outputTokens) / 2;\n\n    return {\n      modelId: selected.id,\n      model: selected,\n      provider: selected.provider,\n      expectedCost,\n      estimatedLatency: this.getLatency(selected),\n      reason: `Fastest option: estimated ${this.getLatency(selected)}ms latency`,\n      alternatives,\n      confidence: 0.85,\n    };\n  }\n\n  private initializeMetrics(): void {\n    // Simulated performance metrics (in production, these would come from monitoring)\n    this.performanceMetrics.set('google/gemini-flash-1.5', 500);\n    this.performanceMetrics.set('google/gemini-pro-1.5', 800);\n    this.performanceMetrics.set('anthropic/claude-3.5-sonnet', 1000);\n    this.performanceMetrics.set('openai/gpt-4-turbo', 1200);\n    this.performanceMetrics.set('anthropic/claude-3-opus', 1500);\n    this.performanceMetrics.set('meta-llama/llama-3.1-70b-instruct', 900);\n    this.performanceMetrics.set('meta-llama/llama-3.1-405b-instruct', 1400);\n  }\n\n  private getPerformanceScore(model: Model): number {\n    const latency = this.getLatency(model);\n    // Lower latency = higher score\n    return 10000 / latency;\n  }\n\n  private getLatency(model: Model): number {\n    return this.performanceMetrics.get(model.id) || 1000;\n  }\n\n  /**\n   * Update performance metrics (for production use)\n   */\n  updateMetrics(modelId: string, latency: number): void {\n    this.performanceMetrics.set(modelId, latency);\n  }\n}\n","import { IRouter, SelectionCriteria, SelectionResult } from '../../types/routing';\nimport { ModelCatalog } from '../ModelCatalog';\nimport { Logger } from '../../utils/logger';\nimport { Model } from '../../types/models';\n\nexport interface BalancedWeights {\n  cost: number;\n  performance: number;\n  capability: number;\n  reliability: number;\n}\n\nexport class BalancedRouter implements IRouter {\n  private weights: BalancedWeights = {\n    cost: 0.4,\n    performance: 0.3,\n    capability: 0.2,\n    reliability: 0.1,\n  };\n\n  private performanceMetrics: Map<string, number> = new Map();\n\n  constructor(\n    private catalog: ModelCatalog,\n    private logger: Logger,\n    weights?: Partial<BalancedWeights>,\n  ) {\n    if (weights) {\n      this.weights = { ...this.weights, ...weights };\n    }\n    this.initializeMetrics();\n  }\n\n  getName(): string {\n    return 'balanced';\n  }\n\n  async route(query: string, criteria: SelectionCriteria): Promise<SelectionResult> {\n    await Promise.resolve(); // Keep async for consistent interface\n    this.logger.debug('BalancedRouter: Finding balanced model', {\n      criteria,\n      weights: this.weights,\n    });\n\n    let candidates = this.catalog.filterModels(criteria);\n\n    // Boost free models by including them if available\n    const freeModels = this.catalog.getFreeModels();\n    if (freeModels.length > 0 && Object.keys(criteria).length === 0) {\n      // Merge free models with candidates, avoiding duplicates\n      const candidateIds = new Set(candidates.map((c) => c.id));\n      const newFreeModels = freeModels.filter((fm) => !candidateIds.has(fm.id));\n      candidates = [...candidates, ...newFreeModels];\n    }\n\n    if (candidates.length === 0) {\n      throw new Error('No models match the specified criteria');\n    }\n\n    // Score each model (free models get a significant boost)\n    const scored = candidates.map((model) => {\n      const isFree = model.pricing.inputTokens === 0 && model.pricing.outputTokens === 0;\n      const baseScore = this.calculateBalancedScore(model);\n      // Give free models a 20 point bonus to make them competitive\n      const finalScore = isFree ? baseScore + 20 : baseScore;\n\n      return {\n        model,\n        score: finalScore,\n        isFree,\n      };\n    });\n\n    // Sort by score (higher is better)\n    scored.sort((a, b) => b.score - a.score);\n\n    const selected = scored[0];\n    const alternatives = scored.slice(1, 4).map((s, idx) => ({\n      modelId: s.model.id,\n      score: s.score,\n      reason: s.isFree\n        ? `Alternative ${idx + 1}: FREE (Score ${s.score.toFixed(2)})`\n        : `Alternative ${idx + 1}: Score ${s.score.toFixed(2)}`,\n    }));\n\n    const expectedCost =\n      (selected.model.pricing.inputTokens + selected.model.pricing.outputTokens) / 2;\n\n    const reasonPrefix = selected.isFree ? 'Best FREE balanced model' : 'Best balanced option';\n    return {\n      modelId: selected.model.id,\n      model: selected.model,\n      provider: selected.model.provider,\n      expectedCost,\n      reason: `${reasonPrefix}: score ${selected.score.toFixed(2)} (cost + performance + capability)`,\n      alternatives,\n      confidence: 0.88,\n    };\n  }\n\n  private calculateBalancedScore(model: Model): number {\n    const costScore = this.calculateCostScore(model);\n    const perfScore = this.calculatePerformanceScore(model);\n    const capScore = this.calculateCapabilityScore(model);\n    const relScore = this.calculateReliabilityScore(model);\n\n    const totalScore =\n      costScore * this.weights.cost +\n      perfScore * this.weights.performance +\n      capScore * this.weights.capability +\n      relScore * this.weights.reliability;\n\n    return totalScore;\n  }\n\n  private calculateCostScore(model: Model): number {\n    const totalCost = model.pricing.inputTokens + model.pricing.outputTokens;\n    // Normalize: cheaper is better, max cost ~100, min ~0.1\n    const normalized = Math.max(0, 1 - totalCost / 100);\n    return normalized * 100;\n  }\n\n  private calculatePerformanceScore(model: Model): number {\n    const latency = this.getLatency(model);\n    // Normalize: faster is better, max latency ~2000ms\n    const normalized = Math.max(0, 1 - latency / 2000);\n    return normalized * 100;\n  }\n\n  private calculateCapabilityScore(model: Model): number {\n    let score = 0;\n    const caps = model.capabilities;\n\n    if (caps.vision) score += 20;\n    if (caps.functionCalling) score += 20;\n    if (caps.tools) score += 15;\n    if (caps.jsonMode) score += 15;\n    if (caps.streaming) score += 10;\n    if (caps.codeGeneration) score += 20;\n\n    // Context window bonus\n    if (model.contextWindow >= 100000) score += 10;\n    else if (model.contextWindow >= 32000) score += 5;\n\n    return Math.min(score, 100);\n  }\n\n  private calculateReliabilityScore(model: Model): number {\n    // Favor well-known providers and non-deprecated models\n    let score = 50;\n\n    if (!model.deprecated) score += 30;\n\n    // Provider reliability (subjective, can be updated with real metrics)\n    const providerScores: Record<string, number> = {\n      anthropic: 20,\n      openai: 20,\n      google: 15,\n      meta: 10,\n      mistral: 15,\n    };\n\n    score += providerScores[model.provider] || 5;\n\n    return Math.min(score, 100);\n  }\n\n  private initializeMetrics(): void {\n    // Simulated latency metrics\n    this.performanceMetrics.set('google/gemini-flash-1.5', 500);\n    this.performanceMetrics.set('google/gemini-pro-1.5', 800);\n    this.performanceMetrics.set('anthropic/claude-3.5-sonnet', 1000);\n    this.performanceMetrics.set('openai/gpt-4-turbo', 1200);\n    this.performanceMetrics.set('anthropic/claude-3-opus', 1500);\n    this.performanceMetrics.set('meta-llama/llama-3.1-70b-instruct', 900);\n    this.performanceMetrics.set('meta-llama/llama-3.1-405b-instruct', 1400);\n    this.performanceMetrics.set('mistralai/mistral-large', 1000);\n  }\n\n  private getLatency(model: Model): number {\n    return this.performanceMetrics.get(model.id) || 1000;\n  }\n\n  /**\n   * Update weights for custom balancing\n   */\n  setWeights(weights: Partial<BalancedWeights>): void {\n    this.weights = { ...this.weights, ...weights };\n\n    // Normalize weights to sum to 1\n    const total = Object.values(this.weights).reduce((a, b) => a + b, 0);\n    this.weights = {\n      cost: this.weights.cost / total,\n      performance: this.weights.performance / total,\n      capability: this.weights.capability / total,\n      reliability: this.weights.reliability / total,\n    };\n  }\n}\n","import { IRouter, SelectionCriteria, SelectionResult } from '../../types/routing';\nimport { ModelCatalog } from '../ModelCatalog';\nimport { Logger } from '../../utils/logger';\nimport { Model, ModelCapabilities } from '../../types/models';\n\nexport class CapabilityRouter implements IRouter {\n  constructor(\n    private catalog: ModelCatalog,\n    private logger: Logger,\n  ) {}\n\n  getName(): string {\n    return 'capability';\n  }\n\n  async route(query: string, criteria: SelectionCriteria): Promise<SelectionResult> {\n    await Promise.resolve(); // Keep async for consistent interface\n    this.logger.debug('CapabilityRouter: Finding best model for capabilities', { criteria });\n\n    // Detect required capabilities from query\n    const detectedCaps = this.detectCapabilities(query);\n\n    // Merge detected capabilities with criteria\n    const requiredCapabilities = {\n      ...detectedCaps,\n      ...(criteria.capabilities || {}),\n    };\n\n    this.logger.debug('Required capabilities', { requiredCapabilities });\n\n    // Filter models by capabilities\n    const candidates = this.catalog.filterModels({\n      ...criteria,\n      capabilities: requiredCapabilities,\n    });\n\n    if (candidates.length === 0) {\n      throw new Error('No models match the required capabilities');\n    }\n\n    // Score models by capability match\n    const scored = candidates.map((model) => ({\n      model,\n      score: this.calculateCapabilityScore(model, requiredCapabilities),\n    }));\n\n    // Sort by score\n    scored.sort((a, b) => b.score - a.score);\n\n    const selected = scored[0];\n    const alternatives = scored.slice(1, 4).map((item, idx) => ({\n      modelId: item.model.id,\n      score: item.score,\n      reason: `Alternative ${idx + 1}: ${this.formatCapabilities(item.model)}`,\n    }));\n\n    const expectedCost =\n      (selected.model.pricing.inputTokens + selected.model.pricing.outputTokens) / 2;\n\n    return {\n      modelId: selected.model.id,\n      model: selected.model,\n      provider: selected.model.provider,\n      expectedCost,\n      reason: `Best capability match: ${this.formatCapabilities(selected.model)}`,\n      alternatives,\n      confidence: 0.85,\n    };\n  }\n\n  private detectCapabilities(query: string): Partial<ModelCapabilities> {\n    const lowerQuery = query.toLowerCase();\n    const capabilities: Partial<ModelCapabilities> = {};\n\n    // Detect vision needs\n    if (\n      lowerQuery.includes('image') ||\n      lowerQuery.includes('picture') ||\n      lowerQuery.includes('photo') ||\n      lowerQuery.includes('visual') ||\n      lowerQuery.includes('see')\n    ) {\n      capabilities.vision = true;\n    }\n\n    // Detect function calling needs\n    if (\n      lowerQuery.includes('function') ||\n      lowerQuery.includes('tool') ||\n      lowerQuery.includes('api') ||\n      lowerQuery.includes('call')\n    ) {\n      capabilities.functionCalling = true;\n      capabilities.tools = true;\n    }\n\n    // Detect JSON mode needs\n    if (\n      lowerQuery.includes('json') ||\n      lowerQuery.includes('structured') ||\n      lowerQuery.includes('format')\n    ) {\n      capabilities.jsonMode = true;\n    }\n\n    // Detect code generation needs\n    if (\n      lowerQuery.includes('code') ||\n      lowerQuery.includes('program') ||\n      lowerQuery.includes('script') ||\n      lowerQuery.includes('implement')\n    ) {\n      capabilities.codeGeneration = true;\n    }\n\n    return capabilities;\n  }\n\n  private calculateCapabilityScore(model: Model, required: Partial<ModelCapabilities>): number {\n    let score = 0;\n    let totalRequired = 0;\n\n    // Check each required capability\n    for (const [key, value] of Object.entries(required)) {\n      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n      if (value !== undefined) {\n        totalRequired++;\n        const capKey = key as keyof ModelCapabilities;\n\n        if (model.capabilities[capKey] === value) {\n          score += 20; // Base score for matching\n        }\n      }\n    }\n\n    // Bonus for additional capabilities\n    const additionalCaps = Object.values(model.capabilities).filter(Boolean).length;\n    score += additionalCaps * 2;\n\n    // Bonus for larger context window (useful for complex tasks)\n    if (model.contextWindow >= 100000) score += 10;\n    else if (model.contextWindow >= 32000) score += 5;\n\n    // Normalize by number of required capabilities\n    if (totalRequired > 0) {\n      score = score / totalRequired;\n    }\n\n    return score;\n  }\n\n  private formatCapabilities(model: Model): string {\n    const caps: string[] = [];\n\n    if (model.capabilities.vision) caps.push('vision');\n    if (model.capabilities.functionCalling) caps.push('functions');\n    if (model.capabilities.tools) caps.push('tools');\n    if (model.capabilities.jsonMode) caps.push('JSON');\n    if (model.capabilities.codeGeneration) caps.push('coding');\n\n    return caps.join(', ') || 'basic';\n  }\n}\n"]}