/**
 * Model Selection Utilities
 *
 * Intelligent model selection for SpecWeave tasks based on complexity,
 * instruction detail, and task characteristics.
 *
 * Strategy (Opus 4.6 Default):
 * - Haiku: Simple/cheap operations, translations, mechanical work
 * - Opus: Default for all complex work, architecture, creative problem-solving
 */
/**
 * Keywords that suggest complex thinking is required (Sonnet territory)
 */
const COMPLEX_KEYWORDS = [
    'design', 'architecture', 'architect', 'evaluate', 'choose', 'decide',
    'compare', 'analyze', 'research', 'investigate', 'plan', 'strategy',
    'refactor', 'optimize', 'tradeoff', 'consider', 'assess', 'review'
];
/**
 * Keywords that suggest simple implementation (Haiku territory)
 */
const SIMPLE_KEYWORDS = [
    'implement', 'create', 'add', 'update', 'fix', 'write', 'install',
    'configure', 'setup', 'integrate', 'connect', 'deploy', 'build',
    'test', 'validate', 'document', 'format', 'style', 'lint'
];
/**
 * Keywords that suggest creative/critical work (Sonnet/Opus territory)
 */
const CREATIVE_KEYWORDS = [
    'novel', 'innovative', 'unique', 'creative', 'original', 'new approach',
    'alternative', 'improve', 'enhance', 'redesign', 'rethink'
];
/**
 * Detects the optimal model for a given task
 *
 * @param task - The task to analyze
 * @param options - Additional context (spec detail level, etc.)
 * @returns Detection result with model recommendation and reasoning
 */
export function detectModelForTask(task, options = {}) {
    const taskText = `${task.content} ${task.description || ''}`.toLowerCase();
    // Score-based detection
    let haikuScore = 0;
    let sonnetScore = 0;
    let opusScore = 0;
    // 1. Keyword analysis
    COMPLEX_KEYWORDS.forEach(keyword => {
        if (taskText.includes(keyword)) {
            sonnetScore += 2;
        }
    });
    SIMPLE_KEYWORDS.forEach(keyword => {
        if (taskText.includes(keyword)) {
            haikuScore += 1;
        }
    });
    CREATIVE_KEYWORDS.forEach(keyword => {
        if (taskText.includes(keyword)) {
            sonnetScore += 3;
            opusScore += 1;
        }
    });
    // 2. Spec/plan reference analysis
    if (task.specReference && options.specDetailLevel && options.specDetailLevel > 0.7) {
        haikuScore += 3; // Has detailed spec reference
    }
    if (options.hasDetailedPlan) {
        haikuScore += 2; // Implementation approach already defined
    }
    if (options.isArchitectural) {
        sonnetScore += 4; // Architectural decisions need thinking
        opusScore += 2;
    }
    // 3. Acceptance criteria analysis
    if (task.acceptanceCriteria && task.acceptanceCriteria.length >= 3) {
        haikuScore += 2; // Clear, specific criteria = can use Haiku
    }
    // 4. Priority analysis (P1 might need more careful attention)
    if (task.priority === 'P1' && !options.hasDetailedPlan) {
        sonnetScore += 1; // Critical work without plan = need thinking
    }
    // 5. Task complexity indicators
    const hasFileReference = /src\/[a-zA-Z0-9\/\-_.]+\.(ts|js|tsx|jsx|py|java|go)/.test(taskText);
    if (hasFileReference) {
        haikuScore += 2; // Specific file paths = concrete instructions
    }
    const hasMultipleSteps = taskText.split(/\n|;|,/).length > 3;
    if (hasMultipleSteps && options.hasDetailedPlan) {
        haikuScore += 1; // Multi-step with plan = can execute mechanically
    }
    // Calculate confidence based on total scores
    const totalScore = haikuScore + sonnetScore + opusScore;
    // Default to opus for best quality
    if (totalScore === 0) {
        return {
            model: 'opus',
            confidence: 0.5,
            reasoning: 'Default to opus for best quality and reasoning'
        };
    }
    const haikuConfidence = haikuScore / totalScore;
    const sonnetConfidence = sonnetScore / totalScore;
    const opusConfidence = opusScore / totalScore;
    // Decision logic - prioritize opus for critical work, haiku for clear instructions
    if (opusScore > 5 && opusConfidence > 0.3) {
        return {
            model: 'opus',
            confidence: opusConfidence,
            reasoning: 'Critical architectural decision requiring deep reasoning'
        };
    }
    if (haikuScore > sonnetScore && haikuConfidence > 0.5) {
        return {
            model: 'haiku',
            confidence: haikuConfidence,
            reasoning: 'Clear instructions with detailed spec/plan - suitable for fast execution'
        };
    }
    if (sonnetScore > haikuScore || sonnetConfidence > 0.4) {
        return {
            model: 'opus',
            confidence: sonnetConfidence,
            reasoning: 'Requires decision-making or complex implementation'
        };
    }
    return {
        model: 'opus',
        confidence: 0.5,
        reasoning: 'Default to opus for best quality and reasoning'
    };
}
/**
 * Batch detect models for multiple tasks
 * Useful when generating tasks.md from plan.md
 */
export function detectModelsForTasks(tasks, options = {}) {
    const results = new Map();
    tasks.forEach(task => {
        const result = detectModelForTask(task, options);
        results.set(task.id, result);
    });
    return results;
}
/**
 * Format model hint for tasks.md
 *
 * @param model - The model tier
 * @returns Formatted string for inclusion in tasks.md
 */
export function formatModelHint(model) {
    const icons = {
        haiku: '⚡', // Fast
        sonnet: '🧠', // Thinking
        opus: '💎' // Premium
    };
    return `${icons[model]} ${model}`;
}
/**
 * Parse model hint from tasks.md line
 *
 * @param line - A line from tasks.md
 * @returns Detected model or null
 */
export function parseModelHint(line) {
    const haikuMatch = /⚡\s*haiku|model:\s*haiku/i.test(line);
    const sonnetMatch = /🧠\s*sonnet|model:\s*sonnet/i.test(line);
    const opusMatch = /💎\s*opus|model:\s*opus/i.test(line);
    if (haikuMatch)
        return 'haiku';
    if (sonnetMatch)
        return 'sonnet';
    if (opusMatch)
        return 'opus';
    return null;
}
/**
 * Cost estimation utilities
 */
export function estimateTaskCost(model, estimatedTokens = 2000) {
    // Approximate costs per 1M tokens (input + output blended)
    const costPer1M = {
        haiku: 1.25, // $0.25 input + $1.25 output = ~$1.25 blended
        sonnet: 15.00, // $3 input + $15 output = ~$15 blended
        opus: 25.00 // $5 input + $25 output = ~$25 blended
    };
    return (estimatedTokens / 1000000) * costPer1M[model];
}
/**
 * Calculate total cost savings when using smart model selection
 */
export function calculateCostSavings(tasksWithModels, averageTokensPerTask = 2000) {
    let optimizedCost = 0;
    let allSonnetCost = 0;
    tasksWithModels.forEach((model) => {
        optimizedCost += estimateTaskCost(model, averageTokensPerTask);
        allSonnetCost += estimateTaskCost('sonnet', averageTokensPerTask);
    });
    const savings = allSonnetCost - optimizedCost;
    const savingsPercent = (savings / allSonnetCost) * 100;
    return {
        optimizedCost,
        allSonnetCost,
        savings,
        savingsPercent
    };
}
//# sourceMappingURL=model-selection.js.map