pub mod counter;
pub mod tiktoken;
pub mod tracker;
pub use counter::{CharRatioCounter, TokenCounter, TrackerTokenUsage};
pub use tiktoken::TiktokenCounter;
pub use tracker::{ModelPricing, TokenTrackingLLM};
use std::sync::LazyLock;
use tiktoken_rs::CoreBPE;
#[derive(Debug, Clone, thiserror::Error)]
#[non_exhaustive]
pub enum TokenCounterError {
#[error("failed to load tiktoken encoder: {0}")]
EncoderLoad(String),
}
static GLOBAL_ENCODER: LazyLock<Result<CoreBPE, TokenCounterError>> = LazyLock::new(|| {
tiktoken_rs::cl100k_base().map_err(|e| TokenCounterError::EncoderLoad(e.to_string()))
});
pub fn count_tokens(text: &str) -> Result<usize, TokenCounterError> {
let encoder = GLOBAL_ENCODER.as_ref().map_err(Clone::clone)?;
Ok(encoder.encode_with_special_tokens(text).len())
}