'use strict';

var aiTokenizer = require('ai-tokenizer');
var _enum = require('../common/enum.cjs');

const tokenizers = {};
async function getTokenizer(encoding = 'o200k_base') {
    const cached = tokenizers[encoding];
    if (cached) {
        return cached;
    }
    const data = encoding === 'claude'
        ? await import('ai-tokenizer/encoding/claude')
        : await import('ai-tokenizer/encoding/o200k_base');
    const instance = new aiTokenizer.Tokenizer(data);
    tokenizers[encoding] = instance;
    return instance;
}
function encodingForModel(model) {
    if (model.toLowerCase().includes('claude')) {
        return 'claude';
    }
    return 'o200k_base';
}
function getTokenCountForMessage(message, getTokenCount) {
    const tokensPerMessage = 3;
    const processValue = (value) => {
        if (Array.isArray(value)) {
            for (const item of value) {
                if (!item ||
                    !item.type ||
                    item.type === _enum.ContentTypes.ERROR ||
                    item.type === _enum.ContentTypes.IMAGE_URL) {
                    continue;
                }
                if (item.type === _enum.ContentTypes.TOOL_CALL && item.tool_call != null) {
                    const toolName = item.tool_call?.name || '';
                    if (toolName != null && toolName && typeof toolName === 'string') {
                        numTokens += getTokenCount(toolName);
                    }
                    const args = item.tool_call?.args || '';
                    if (args != null && args && typeof args === 'string') {
                        numTokens += getTokenCount(args);
                    }
                    const output = item.tool_call?.output || '';
                    if (output != null && output && typeof output === 'string') {
                        numTokens += getTokenCount(output);
                    }
                    continue;
                }
                const nestedValue = item[item.type];
                if (!nestedValue) {
                    continue;
                }
                processValue(nestedValue);
            }
        }
        else if (typeof value === 'string') {
            numTokens += getTokenCount(value);
        }
        else if (typeof value === 'number') {
            numTokens += getTokenCount(value.toString());
        }
        else if (typeof value === 'boolean') {
            numTokens += getTokenCount(value.toString());
        }
    };
    let numTokens = tokensPerMessage;
    processValue(message.content);
    return numTokens;
}
/**
 * Creates a token counter function using the specified encoding.
 * Lazily loads the encoding data on first use via dynamic import.
 */
const createTokenCounter = async (encoding = 'o200k_base') => {
    const tok = await getTokenizer(encoding);
    const countTokens = (text) => tok.count(text);
    return (message) => getTokenCountForMessage(message, countTokens);
};
/** Utility to manage the token encoder lifecycle explicitly. */
const TokenEncoderManager = {
    async initialize() {
        // No-op: ai-tokenizer is synchronously initialized from bundled data.
    },
    reset() {
        for (const key of Object.keys(tokenizers)) {
            delete tokenizers[key];
        }
    },
    isInitialized() {
        return Object.keys(tokenizers).length > 0;
    },
};

exports.TokenEncoderManager = TokenEncoderManager;
exports.createTokenCounter = createTokenCounter;
exports.encodingForModel = encodingForModel;
exports.getTokenCountForMessage = getTokenCountForMessage;
//# sourceMappingURL=tokens.cjs.map
