use regex::Regex;
use std::sync::LazyLock;
fn compile(pattern: &str) -> Regex {
Regex::new(pattern).expect("invalid regex pattern")
}
pub static LLAMA_START: LazyLock<Regex> =
LazyLock::new(|| compile(r"(?i)(llama.*server|ggml\s+version)"));
pub static LOADING_MODEL: LazyLock<Regex> = LazyLock::new(|| compile(r"(?i)llama_model_loader"));
pub static LOADED_META: LazyLock<Regex> =
LazyLock::new(|| compile(r"(?i)(loaded\s+\d+\s+meta|meta\s+data)"));
pub static LOAD_TENSORS: LazyLock<Regex> = LazyLock::new(|| compile(r"(?i)load tensors:"));
pub static SERVER_LISTENING: LazyLock<Regex> = LazyLock::new(|| {
compile(r"(?i)(server listening|http server listening|load_model:\s*initializing\s+slots)")
});
pub static LOADING_TENSOR: LazyLock<Regex> =
LazyLock::new(|| compile(r"(?i)loading tensor\s+(\d+)\s+(?:of|out of)\s+(\d+)"));
pub static OFFLOADING_LAYERS: LazyLock<Regex> =
LazyLock::new(|| compile(r"(?i)offloading\s+(\d+)\s+repeating layers"));
pub static OFFLOADED_LAYERS: LazyLock<Regex> =
LazyLock::new(|| compile(r"(?i)offloaded\s+(\d+)\s*(?:out\s+of|/)\s*(\d+)\s*layers"));
pub static MODEL_BUFFER_SIZE: LazyLock<Regex> = LazyLock::new(|| {
compile(
r"(?i)((?:vulkan\d|roc\d|cuda|cpu|metal)?(?:\s*))model buffer size\s*=\s*([\d.]+)\s*MiB",
)
});
pub static KV_BUFFER_SIZE: LazyLock<Regex> =
LazyLock::new(|| compile(r"(?i)kv buffer size\s*=\s*([\d.]+)\s*MiB"));
pub static LOADING_MODEL_PROGRESS: LazyLock<Regex> =
LazyLock::new(|| compile(r"(?i)loading model:\s*(\d+)\s*(?:of|out of|/)\s*(\d+)"));
pub fn is_loading_error(msg: &str) -> bool {
let lower = msg.to_lowercase();
lower.contains("out of memory")
|| lower.contains("out_of_memory")
|| lower.contains("out_of_device_memory")
|| lower.contains("outofmemory")
|| lower.contains("outofdevicememory")
|| lower.contains("failed to load")
|| lower.contains("failed loading")
|| lower.contains("failed to initialize")
|| lower.contains("load failed")
|| lower.contains("load_model: error")
|| lower.contains("error loading")
|| lower.contains("exception")
|| lower.contains("vk::systemerror")
}
pub fn is_oom_error(msg: &str) -> bool {
let lower = msg.to_lowercase();
lower.contains("out of memory")
|| lower.contains("out_of_memory")
|| lower.contains("out_of_device_memory")
|| lower.contains("outofmemory")
|| lower.contains("outofdevicememory")
}