Ctrl K
ComunidadGuías…

scripts/chatGPTCostEstimator.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bun
/**
 * This script estimates the cost of OpenAI API calls based on input and output tokens.
 */
import CLI from 'expensify-common/CLI';

import COLORS from './utils/COLORS';

/**
 * Utility class for estimating OpenAI API costs.
 */
class ChatGPTCostEstimator {
    /** Cost per million input tokens for GPT 5.1 */
    static readonly GPT_5_1_INPUT_COST_PER_MILLION = 1.25;

    /** Cost per million output tokens for GPT 5.1 */
    static readonly GPT_5_1_OUTPUT_COST_PER_MILLION = 10.0;

    /** Average number of tokens per character (rule of thumb for English-ish text) */
    static readonly TOKENS_PER_CHAR = 0.25;

    /** Discount rate for cached prompt tokens (cached tokens cost ~10% of full price) */
    static readonly CACHED_INPUT_DISCOUNT = 0.1;

    /**
     * Calculates the estimated cost for OpenAI API calls based on input and output tokens.
     *
     * @param inputTokens - Total number of uncached input tokens
     * @param outputTokens - Total number of output tokens
     * @param cachedInputTokens - Total number of cached input tokens (default: 0)
     * @returns Estimated cost in USD
     */
    static getTotalEstimatedCost(inputTokens: number, outputTokens: number, cachedInputTokens = 0): number {
        const uncachedInputCost = (inputTokens / 1_000_000) * ChatGPTCostEstimator.GPT_5_1_INPUT_COST_PER_MILLION;
        const cachedInputCost = (cachedInputTokens / 1_000_000) * ChatGPTCostEstimator.GPT_5_1_INPUT_COST_PER_MILLION * ChatGPTCostEstimator.CACHED_INPUT_DISCOUNT;
        const outputCost = (outputTokens / 1_000_000) * ChatGPTCostEstimator.GPT_5_1_OUTPUT_COST_PER_MILLION;
        return uncachedInputCost + cachedInputCost + outputCost;
    }
}

if (require.main === module) {
    /* eslint-disable @typescript-eslint/naming-convention */
    const cli = new CLI({
        namedArgs: {
            'input-tokens': {
                description: 'Total number of input tokens',
                parse: (val: string): number => {
                    const parsed = parseInt(val, 10);
                    if (Number.isNaN(parsed) || parsed < 0) {
                        throw new Error('Input tokens must be a non-negative integer');
                    }
                    return parsed;
                },
            },
            'output-tokens': {
                description: 'Total number of output tokens',
                parse: (val: string): number => {
                    const parsed = parseInt(val, 10);
                    if (Number.isNaN(parsed) || parsed < 0) {
                        throw new Error('Output tokens must be a non-negative integer');
                    }
                    return parsed;
                },
            },
        },
    } as const);
    /* eslint-enable @typescript-eslint/naming-convention */

    const inputTokens = cli.namedArgs['input-tokens'];
    const outputTokens = cli.namedArgs['output-tokens'];
    const totalCost = ChatGPTCostEstimator.getTotalEstimatedCost(inputTokens, outputTokens);

    console.log('\n=== ChatGPT Cost Estimator ===\n');
    console.log('Pricing (GPT 5.1):');
    console.log(`  Input:  $${ChatGPTCostEstimator.GPT_5_1_INPUT_COST_PER_MILLION.toFixed(2)}/million tokens`);
    console.log(`  Output: $${ChatGPTCostEstimator.GPT_5_1_OUTPUT_COST_PER_MILLION.toFixed(2)}/million tokens\n`);
    console.log('Your estimate:');
    console.log(`  Input tokens:  ${inputTokens.toLocaleString()}`);
    console.log(`  Output tokens: ${outputTokens.toLocaleString()}`);
    console.log(`  ${'─'.repeat(30)}`);
    console.log(`  Estimated cost: ${COLORS.BOLD}$${totalCost.toFixed(2)} USD${COLORS.RESET}\n`);
}

export default ChatGPTCostEstimator;