const CHARS_PER_TOKEN_BY_PROVIDER = {
	anthropic: 3.5,
	openai: 4.0,
	google: 4.0,
	mistral: 3.8,
	bedrock: 3.5,
	unknown: 4.0,
};
let encoder = null;
let encoderFailed = false;
async function getEncoder() {
	if (encoder) return encoder;
	if (encoderFailed) return null;
	try {
		// @ts-expect-error — tiktoken may not have type declarations in extensions tsconfig
		const tiktoken = await import("tiktoken");
		encoder = tiktoken.encoding_for_model("gpt-4o");
		return encoder;
	} catch {
		encoderFailed = true;
		return null;
	}
}
/**
 * Count tokens in text using tiktoken if available, otherwise estimate.
 */
export async function countTokens(text) {
	const enc = await getEncoder();
	if (enc) {
		const tokens = enc.encode(text);
		return tokens.length;
	}
	return Math.ceil(text.length / 4);
}
/**
 * Synchronously count tokens (requires tiktoken to be pre-loaded).
 */
export function countTokensSync(text) {
	if (encoder) {
		return encoder.encode(text).length;
	}
	return Math.ceil(text.length / 4);
}
/**
 * Initialize the token counter by loading tiktoken encoder.
 */
export async function initTokenCounter() {
	const enc = await getEncoder();
	return enc !== null;
}
/**
 * Check if tiktoken encoder is loaded for accurate token counting.
 */
export function isAccurateCountingAvailable() {
	return encoder !== null;
}
/**
 * Get the provider-specific characters-per-token ratio for estimation.
 */
export function getCharsPerToken(provider) {
	return (
		CHARS_PER_TOKEN_BY_PROVIDER[provider] ?? CHARS_PER_TOKEN_BY_PROVIDER.unknown
	);
}
/**
 * Estimate token count for text using provider-specific ratio.
 */
export function estimateTokensForProvider(text, provider) {
	const ratio = getCharsPerToken(provider);
	return Math.ceil(text.length / ratio);
}
