diff --git a/Cargo.lock b/Cargo.lock index 09eba0d..756aa2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -659,7 +659,7 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "llm-ls" -version = "0.2.1" +version = "0.2.2" dependencies = [ "home", "reqwest", diff --git a/crates/llm-ls/Cargo.toml b/crates/llm-ls/Cargo.toml index 206edcf..d37966c 100644 --- a/crates/llm-ls/Cargo.toml +++ b/crates/llm-ls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "llm-ls" -version = "0.2.1" +version = "0.2.2" edition = "2021" [[bin]] diff --git a/crates/llm-ls/src/main.rs b/crates/llm-ls/src/main.rs index 7afdcc1..d9e60cb 100644 --- a/crates/llm-ls/src/main.rs +++ b/crates/llm-ls/src/main.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; use std::fmt::Display; use std::path::{Path, PathBuf}; use std::sync::Arc; -use std::time::Instant; +use std::time::{Duration, Instant}; use tokenizers::Tokenizer; use tokio::io::AsyncWriteExt; use tokio::sync::RwLock; @@ -16,6 +16,7 @@ use tracing::{debug, error, info}; use tracing_appender::rolling; use tracing_subscriber::EnvFilter; +const MAX_WARNING_REPEAT: Duration = Duration::from_secs(3_600); const NAME: &str = "llm-ls"; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -121,6 +122,7 @@ struct Backend { unsafe_http_client: reqwest::Client, workspace_folders: Arc>>>, tokenizer_map: Arc>>>, + unauthenticated_warn_at: Arc>, } #[derive(Debug, Deserialize, Serialize)] @@ -454,6 +456,16 @@ impl Backend { let document = document_map .get(params.text_document_position.text_document.uri.as_str()) .ok_or_else(|| internal_error("failed to find document"))?; + if params.api_token.is_none() { + let now = Instant::now(); + let unauthenticated_warn_at = self.unauthenticated_warn_at.read().await; + if now.duration_since(*unauthenticated_warn_at) > MAX_WARNING_REPEAT { + drop(unauthenticated_warn_at); + self.client.show_message(MessageType::WARNING, "You are currently unauthenticated and will get rate limited. To reduce rate limiting, login with your API Token and consider subscribing to PRO: https://huggingface.co/pricing#pro").await; + let mut unauthenticated_warn_at = self.unauthenticated_warn_at.write().await; + *unauthenticated_warn_at = Instant::now(); + } + } let tokenizer = get_tokenizer( ¶ms.model, &mut *self.tokenizer_map.write().await, @@ -631,6 +643,11 @@ async fn main() { unsafe_http_client, workspace_folders: Arc::new(RwLock::new(None)), tokenizer_map: Arc::new(RwLock::new(HashMap::new())), + unauthenticated_warn_at: Arc::new(RwLock::new( + Instant::now() + .checked_sub(MAX_WARNING_REPEAT) + .expect("instant to be in bounds"), + )), }) .custom_method("llm-ls/getCompletions", Backend::get_completions) .finish();