Fix clippy warnings: reduce 17 warnings to 0
All checks were successful
BotServer CI/CD / build (push) Successful in 6m58s

- Fix double_ended_iterator_last: use next_back() instead of last()
- Fix manual_clamp: use .clamp() instead of min().max()
- Fix too_many_arguments: create KbInjectionContext struct
- Fix needless_borrow: remove unnecessary & reference
- Fix let_and_return: return value directly
- Fix await_holding_lock: drop guard before await
- Fix collapsible_else_if: collapse nested if-else

All changes verified with cargo clippy (0 warnings, 0 errors)
Note: Local botserver crashes with existing panic during LocalFileMonitor initialization
This panic exists in original code too, not caused by these changes
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-04-03 22:34:43 -03:00
parent 9f55e864ff
commit 4d7297243e
9 changed files with 63 additions and 50 deletions

View file

@ -184,7 +184,7 @@ async fn think_kb_search(
/// Calculate confidence score based on multiple factors
fn calculate_confidence(avg_relevance: f64, result_count: usize, source_count: usize) -> f64 {
// Base confidence from average relevance (0.0 to 1.0)
let relevance_factor = avg_relevance.min(1.0).max(0.0);
let relevance_factor = avg_relevance.clamp(0.0, 1.0);
// Boost confidence with more results (diminishing returns)
let result_factor = (result_count as f64 / 10.0).min(1.0);

View file

@ -39,6 +39,15 @@ pub struct KbSearchResult {
pub chunk_tokens: usize,
}
pub struct KbInjectionContext<'a> {
pub session_id: Uuid,
pub bot_id: Uuid,
pub bot_name: &'a str,
pub user_query: &'a str,
pub messages: &'a mut serde_json::Value,
pub max_context_tokens: usize,
}
#[derive(Debug)]
pub struct KbContextManager {
kb_manager: Arc<KnowledgeBaseManager>,
@ -479,28 +488,23 @@ fn estimate_tokens(text: &str) -> usize {
pub async fn inject_kb_context(
kb_manager: Arc<KnowledgeBaseManager>,
db_pool: DbPool,
session_id: Uuid,
bot_id: Uuid,
bot_name: &str,
user_query: &str,
messages: &mut serde_json::Value,
max_context_tokens: usize,
context: KbInjectionContext<'_>,
) -> Result<()> {
let context_manager = KbContextManager::new(kb_manager.clone(), db_pool.clone());
let kb_contexts = context_manager
.search_active_kbs(session_id, bot_id, bot_name, user_query, 5, max_context_tokens / 2)
.search_active_kbs(context.session_id, context.bot_id, context.bot_name, context.user_query, 5, context.max_context_tokens / 2)
.await?;
let website_contexts = context_manager
.search_active_websites(session_id, user_query, 5, max_context_tokens / 2)
.search_active_websites(context.session_id, context.user_query, 5, context.max_context_tokens / 2)
.await?;
let mut all_contexts = kb_contexts;
all_contexts.extend(website_contexts);
if all_contexts.is_empty() {
debug!("No KB or website context found for session {}", session_id);
debug!("No KB or website context found for session {}", context.session_id);
return Ok(());
}
@ -526,10 +530,10 @@ pub async fn inject_kb_context(
info!(
"Injecting {} characters of KB/website context into prompt for session {}",
sanitized_context.len(),
session_id
context.session_id
);
if let Some(messages_array) = messages.as_array_mut() {
if let Some(messages_array) = context.messages.as_array_mut() {
let system_msg_idx = messages_array.iter().position(|m| m["role"] == "system");
if let Some(idx) = system_msg_idx {

View file

@ -676,15 +676,18 @@ impl BotOrchestrator {
}
if let Some(kb_manager) = self.state.kb_manager.as_ref() {
let context = crate::core::bot::kb_context::KbInjectionContext {
session_id,
bot_id: session.bot_id,
bot_name: &bot_name_for_context,
user_query: &message_content,
messages: &mut messages,
max_context_tokens: 8000,
};
if let Err(e) = inject_kb_context(
kb_manager.clone(),
self.state.conn.clone(),
session_id,
session.bot_id,
&bot_name_for_context,
&message_content,
&mut messages,
8000,
context,
)
.await
{

View file

@ -71,14 +71,13 @@ INSTALL_LOCK = true
// Try to create admin user and get runner token via HTTP API
// Note: Forgejo CLI binary may segfault on some systems, so we use curl
let runner_token = match try_alm_api_setup(alm_url, &username, &password, data_path.to_str().unwrap_or(".")).await {
let runner_token = match try_alm_api_setup(alm_url, username, &password, data_path.to_str().unwrap_or(".")).await {
Ok(token) => token,
Err(e) => {
warn!("ALM automated setup unavailable via API: {}", e);
warn!("ALM will need manual configuration. Create admin user and runner token via web UI.");
// Store placeholder credentials
let placeholder_token = generate_random_string(40);
placeholder_token
generate_random_string(40)
}
};

View file

@ -1548,7 +1548,7 @@ VAULT_CACERT={}
}
// Write default credentials to Vault for all components
self.seed_vault_defaults(&vault_addr, &root_token, &ca_cert, &vault_bin)?;
self.seed_vault_defaults(&vault_addr, root_token, &ca_cert, &vault_bin)?;
Ok(())
}

View file

@ -40,8 +40,12 @@ pub async fn init_secrets_manager() -> Result<()> {
}
pub async fn get_database_url() -> Result<String> {
let manager = {
let guard = SECRETS_MANAGER.read().map_err(|e| anyhow::anyhow!("Lock poisoned: {}", e))?;
if let Some(ref manager) = *guard {
(*guard).as_ref().map(|manager| manager.clone())
};
if let Some(manager) = manager {
return manager.get_database_url().await;
}
@ -114,9 +118,17 @@ pub async fn create_s3_operator(
};
let (access_key, secret_key) = if config.access_key.is_empty() || config.secret_key.is_empty() {
let (manager, is_vault_enabled) = {
let guard = SECRETS_MANAGER.read().map_err(|e| format!("Lock poisoned: {}", e))?;
if let Some(ref manager) = *guard {
if manager.is_enabled() {
(Some(manager.clone()), manager.is_enabled())
} else {
(None, false)
}
};
match (manager, is_vault_enabled) {
(Some(manager), true) => {
match manager.get_drive_credentials().await {
Ok((ak, sk)) => (ak, sk),
Err(e) => {
@ -124,11 +136,8 @@ pub async fn create_s3_operator(
(config.access_key.clone(), config.secret_key.clone())
}
}
} else {
(config.access_key.clone(), config.secret_key.clone())
}
} else {
(config.access_key.clone(), config.secret_key.clone())
_ => (config.access_key.clone(), config.secret_key.clone())
}
} else {
(config.access_key.clone(), config.secret_key.clone())

View file

@ -333,8 +333,7 @@ impl LocalFileMonitor {
let path = entry.path();
if path.is_dir() {
stack.push(path);
} else {
if let Ok(meta) = tokio::fs::metadata(&path).await {
} else if let Ok(meta) = tokio::fs::metadata(&path).await {
let mtime = meta.modified()
.map(|t| t.duration_since(SystemTime::UNIX_EPOCH).map(|d| d.as_secs()).unwrap_or(0))
.unwrap_or(0);
@ -345,7 +344,6 @@ impl LocalFileMonitor {
}
}
}
}
Ok((hash, file_count))
}

View file

@ -337,11 +337,11 @@ pub async fn init_redis() -> Option<Arc<redis::Client>> {
Ok(mut conn) => {
match redis::cmd("PING").query::<String>(&mut conn) {
Ok(response) if response == "PONG" => {
log::info!("Cache initialized - Valkey connected via {}", cache_url.split('@').last().unwrap_or(&cache_url));
log::info!("Cache initialized - Valkey connected via {}", cache_url.split('@').next_back().unwrap_or(&cache_url));
Ok(Some(Arc::new(client)))
}
Ok(response) => {
log::info!("Cache initialized - Valkey connected via {} (PING: {})", cache_url.split('@').last().unwrap_or(&cache_url), response);
log::info!("Cache initialized - Valkey connected via {} (PING: {})", cache_url.split('@').next_back().unwrap_or(&cache_url), response);
Ok(Some(Arc::new(client)))
}
Err(e) => {

View file

@ -38,12 +38,12 @@ impl TlsIntegration {
let qdrant_secure = qdrant_url.replace("http://", "https://");
let qdrant_port: u16 = qdrant_url
.split(':')
.last()
.next_back()
.and_then(|p| p.parse().ok())
.unwrap_or(6333);
let qdrant_tls_port: u16 = qdrant_secure
.split(':')
.last()
.next_back()
.and_then(|p| p.parse().ok())
.unwrap_or(6334);
@ -62,12 +62,12 @@ impl TlsIntegration {
let llm_secure = llm_url.replace("http://", "https://");
let llm_port: u16 = llm_url
.split(':')
.last()
.next_back()
.and_then(|p| p.parse().ok())
.unwrap_or(8081);
let llm_tls_port: u16 = llm_secure
.split(':')
.last()
.next_back()
.and_then(|p| p.parse().ok())
.unwrap_or(8444);
@ -105,7 +105,7 @@ impl TlsIntegration {
};
let drive_port: u16 = drive_host
.split(':')
.last()
.next_back()
.and_then(|p| p.parse().ok())
.unwrap_or(9100);
@ -123,12 +123,12 @@ impl TlsIntegration {
let directory_secure = directory_url.replace("http://", "https://");
let directory_port: u16 = directory_url
.split(':')
.last()
.next_back()
.and_then(|p| p.parse().ok())
.unwrap_or(9000);
let directory_tls_port: u16 = directory_secure
.split(':')
.last()
.next_back()
.and_then(|p| p.parse().ok())
.unwrap_or(8446);