// Rough tokens consumed per dev-hour of Claude Code work (empirical approximation)
const OPUS_TOKENS_PER_DEV_HOUR = 25_000;
const SONNET_TOKENS_PER_DEV_HOUR = 45_000;
// Blended input+output cost per token (Anthropic 2026 pricing)
const OPUS_COST_PER_TOKEN = 0.00004; // ~$40/1M blended
const SONNET_COST_PER_TOKEN = 0.000008; // ~$8/1M blended
/** Returns true when all token/cost actuals are zero (agent did not provide them). */
export function actualsAreMissing(actuals) {
    return actuals.tokensOpus === 0 && actuals.tokensSonnet === 0 && actuals.apiCostUsd === 0;
}
/**
 * Auto-fills zero token/cost fields in actuals using the spec's estimation data.
 * Marks the result with `estimated: true` so reports can distinguish real vs auto values.
 */
export function autoFillActuals(actuals, estimation) {
    if (!actualsAreMissing(actuals)) {
        return actuals;
    }
    const hours = actuals.devHours > 0 ? actuals.devHours : estimation.devHours;
    let tokensOpus = 0;
    let tokensSonnet = 0;
    if (estimation.recommendedModel === 'opus') {
        tokensOpus = Math.round(hours * OPUS_TOKENS_PER_DEV_HOUR);
    }
    else if (estimation.recommendedModel === 'sonnet') {
        tokensSonnet = Math.round(hours * SONNET_TOKENS_PER_DEV_HOUR);
    }
    else {
        // mixed: 40% opus, 60% sonnet
        tokensOpus = Math.round(hours * OPUS_TOKENS_PER_DEV_HOUR * 0.4);
        tokensSonnet = Math.round(hours * SONNET_TOKENS_PER_DEV_HOUR * 0.6);
    }
    const apiCostUsd = tokensOpus * OPUS_COST_PER_TOKEN + tokensSonnet * SONNET_COST_PER_TOKEN;
    const humanCostUsd = actuals.humanCostUsd > 0 ? actuals.humanCostUsd : hours * estimation.hourlyRate;
    const totalCostUsd = apiCostUsd + humanCostUsd;
    return {
        ...actuals,
        tokensOpus,
        tokensSonnet,
        apiCostUsd: parseFloat(apiCostUsd.toFixed(4)),
        humanCostUsd: parseFloat(humanCostUsd.toFixed(4)),
        totalCostUsd: parseFloat(totalCostUsd.toFixed(4)),
        estimated: true,
    };
}
/**
 * Creates a default Actuals object from the spec's estimation when the agent
 * did not provide actuals at all. Token/cost fields are auto-estimated.
 */
export function createDefaultActuals(estimation) {
    const base = {
        devHours: estimation.devHours,
        reviewHours: estimation.reviewHours,
        tokensOpus: 0,
        tokensSonnet: 0,
        apiCostUsd: 0,
        humanCostUsd: estimation.humanCostUsd,
        totalCostUsd: 0,
        completedAt: new Date().toISOString(),
        notes: '',
    };
    return autoFillActuals(base, estimation);
}
//# sourceMappingURL=actuals-estimator.js.map